<commit_before>// problem57.go
//
// It is possible to show that the square root of two can be expressed as an
// infinite continued fraction.
//
//     √ 2 = 1 + 1/(2 + 1/(2 + 1/(2 + ... ))) = 1.414213...
//
// By expanding this for the first four iterations, we get:
//
//     1 + 1/2 = 3/2 = 1.5
//     1 + 1/(2 + 1/2) = 7/5 = 1.4
//     1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666...
//     1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379...
//
// The next three expansions are 99/70, 239/169, and 577/408, but the eighth
// expansion, 1393/985, is the first example where the number of digits in the
// numerator exceeds the number of digits in the denominator. In the first
// one-thousand expansions, how many fractions contain a numerator with more
// digits than denominator?

package main

import (
	"fmt"
	"math/big"
)

func numDigits(n *big.Int) int {
	return len(n.String())
}

func checkNumerator(x *big.Rat) bool {
	num, denom := x.Num(), x.Denom()
	return numDigits(num) > numDigits(denom)
}

// How many fractions contain a numerator with more digits than the denominator?
func problem57() int {
	sum := 0           // Number of fractions meeting the description.
	const limit = 1000 // Given in problem description.
	one := big.NewRat(1, 1)
	two := big.NewRat(2, 1)

	// result will be re-used each iteration to store the
	// current value of the fractional expansion.
	result := new(big.Rat)
	// tail will be re-used each iteration to store the
	// current value of the repeating component of the expansion.
	// That component is 2, (2 + 1/2), (2 + 1/(2 + 1/2)), ...
	tail := big.NewRat(2, 1)

	for i := 0; i < limit; i++ {
		temp := new(big.Rat).Set(tail)
		tail.Add(two, temp.Inv(tail))   // tail = (2 + 1/tail)
		result.Add(one, temp.Inv(tail)) // result = (1 + 1/tail)
		if checkNumerator(result) {
			sum++
		}
	}
	return sum
}

func main() {
	ans := problem57()
	fmt.Println(ans)
}
<commit_msg>Remove unnecessary method call in problem57.go<commit_after>// problem57.go
//
// It is possible to show that the square root of two can be expressed as an
// infinite continued fraction.
//
//     √ 2 = 1 + 1/(2 + 1/(2 + 1/(2 + ... ))) = 1.414213...
//
// By expanding this for the first four iterations, we get:
//
//     1 + 1/2 = 3/2 = 1.5
//     1 + 1/(2 + 1/2) = 7/5 = 1.4
//     1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666...
//     1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379...
//
// The next three expansions are 99/70, 239/169, and 577/408, but the eighth
// expansion, 1393/985, is the first example where the number of digits in the
// numerator exceeds the number of digits in the denominator. In the first
// one-thousand expansions, how many fractions contain a numerator with more
// digits than denominator?

package main

import (
	"fmt"
	"math/big"
)

func numDigits(n *big.Int) int {
	return len(n.String())
}

func checkNumerator(x *big.Rat) bool {
	num, denom := x.Num(), x.Denom()
	return numDigits(num) > numDigits(denom)
}

// How many fractions contain a numerator with more digits than the denominator?
func problem57() int {
	sum := 0           // Number of fractions meeting the description.
	const limit = 1000 // Given in problem description.
	one := big.NewRat(1, 1)
	two := big.NewRat(2, 1)

	// result will be re-used each iteration to store the
	// current value of the fractional expansion.
	result := new(big.Rat)
	// tail will be re-used each iteration to store the
	// current value of the repeating component of the expansion.
	// That component is 2, (2 + 1/2), (2 + 1/(2 + 1/2)), ...
	tail := big.NewRat(2, 1)

	for i := 0; i < limit; i++ {
		temp := new(big.Rat)
		tail.Add(two, temp.Inv(tail))   // tail = (2 + 1/tail)
		result.Add(one, temp.Inv(tail)) // result = (1 + 1/tail)
		if checkNumerator(result) {
			sum++
		}
	}
	return sum
}

func main() {
	ans := problem57()
	fmt.Println(ans)
}
<|endoftext|>


<commit_before>package types_test

import (
	"go/ast"
	"testing"

	"github.com/a8m/expect"
	"github.com/nelsam/hel/types"
)

func TestLoad_NoTestFiles(t *testing.T) {
	expect := expect.New(t)

	mockGoDir := newMockGoDir()
	mockGoDir.PathOutput.ret0 <- "/some/path"
	mockGoDir.PackagesOutput.ret0 <- map[string]*ast.Package{
		"foo": {
			Name: "foo",
			Files: map[string]*ast.File{
				"foo.go": parse(expect, "type Foo interface {}"),
			},
		},
	}
	found := types.Load(mockGoDir)
	expect(found).To.Have.Len(1)
	expect(found[0].Len()).To.Equal(1)
	expect(found[0].Dir()).To.Equal("/some/path")
	expect(found[0].Package()).To.Equal("foo")
	expect(found[0].TestPackage()).To.Equal("foo_test")
}

func TestLoad_TestFilesInTestPackage(t *testing.T) {
	expect := expect.New(t)

	mockGoDir := newMockGoDir()
	mockGoDir.PathOutput.ret0 <- "/some/path"
	mockGoDir.PackagesOutput.ret0 <- map[string]*ast.Package{
		"foo": {
			Name: "foo",
			Files: map[string]*ast.File{
				"foo.go": parse(expect, "type Foo interface{}"),
			},
		},
		"foo_test": {
			Name: "foo_test",
			Files: map[string]*ast.File{
				"foo_test.go": parse(expect, "type Bar interface{}"),
			},
		},
	}
	found := types.Load(mockGoDir)
	expect(found).To.Have.Len(1)
	expect(found[0].Len()).To.Equal(1)
	expect(found[0].Package()).To.Equal("foo")
	expect(found[0].TestPackage()).To.Equal("foo_test")
}

func TestLoad_TestFilesInNonTestPackage(t *testing.T) {
	expect := expect.New(t)

	mockGoDir := newMockGoDir()
	mockGoDir.PathOutput.ret0 <- "/some/path"
	mockGoDir.PackagesOutput.ret0 <- map[string]*ast.Package{
		"foo": {
			Name: "foo",
			Files: map[string]*ast.File{
				"foo.go":      parse(expect, "type Foo interface{}"),
				"foo_test.go": parse(expect, "type Bar interface{}"),
			},
		},
	}
	found := types.Load(mockGoDir)
	expect(found).To.Have.Len(1)
	expect(found[0].Len()).To.Equal(1)
	expect(found[0].Package()).To.Equal("foo")
	expect(found[0].TestPackage()).To.Equal("foo")
}

func TestFilter(t *testing.T) {
	expect := expect.New(t)

	mockGoDir := newMockGoDir()
	mockGoDir.PathOutput.ret0 <- "/some/path"
	mockGoDir.PackagesOutput.ret0 <- map[string]*ast.Package{
		"foo": {
			Name: "foo",
			Files: map[string]*ast.File{
				"foo.go": parse(expect, `
    type Foo interface {}
    type Bar interface {}
    type FooBar interface {}
    type BarFoo interface {}
    `),
			},
		},
	}
	found := types.Load(mockGoDir)
	expect(found).To.Have.Len(1)
	expect(found[0].Len()).To.Equal(4)

	notFiltered := found.Filter()
	expect(notFiltered).To.Have.Len(1)
	expect(notFiltered[0].Len()).To.Equal(4)

	foos := found.Filter("Foo")
	expect(foos).To.Have.Len(1)
	expect(foos[0].Len()).To.Equal(1)
	expect(foos[0].ExportedTypes()[0].Name.String()).To.Equal("Foo")

	fooPrefixes := found.Filter("Foo.*")
	expect(fooPrefixes).To.Have.Len(1)
	expect(fooPrefixes[0].Len()).To.Equal(2)
	expect(fooPrefixes[0].ExportedTypes()[0].Name.String()).To.Equal("Foo")
	expect(fooPrefixes[0].ExportedTypes()[1].Name.String()).To.Equal("FooBar")

	fooPostfixes := found.Filter(".*Foo")
	expect(fooPostfixes).To.Have.Len(1)
	expect(fooPostfixes[0].Len()).To.Equal(2)
	expect(fooPostfixes[0].ExportedTypes()[0].Name.String()).To.Equal("Foo")
	expect(fooPostfixes[0].ExportedTypes()[1].Name.String()).To.Equal("BarFoo")

	fooContainers := found.Filter("Foo.*", ".*Foo")
	expect(fooContainers).To.Have.Len(1)
	expect(fooContainers[0].Len()).To.Equal(3)
	expect(fooContainers[0].ExportedTypes()[0].Name.String()).To.Equal("Foo")
	expect(fooContainers[0].ExportedTypes()[1].Name.String()).To.Equal("FooBar")
	expect(fooContainers[0].ExportedTypes()[2].Name.String()).To.Equal("BarFoo")
}
<commit_msg>Fix flakey test (apparently we can't rely on order from ast)<commit_after>package types_test

import (
	"go/ast"
	"testing"

	"github.com/a8m/expect"
	"github.com/nelsam/hel/types"
)

func TestLoad_NoTestFiles(t *testing.T) {
	expect := expect.New(t)

	mockGoDir := newMockGoDir()
	mockGoDir.PathOutput.ret0 <- "/some/path"
	mockGoDir.PackagesOutput.ret0 <- map[string]*ast.Package{
		"foo": {
			Name: "foo",
			Files: map[string]*ast.File{
				"foo.go": parse(expect, "type Foo interface {}"),
			},
		},
	}
	found := types.Load(mockGoDir)
	expect(found).To.Have.Len(1)
	expect(found[0].Len()).To.Equal(1)
	expect(found[0].Dir()).To.Equal("/some/path")
	expect(found[0].Package()).To.Equal("foo")
	expect(found[0].TestPackage()).To.Equal("foo_test")
}

func TestLoad_TestFilesInTestPackage(t *testing.T) {
	expect := expect.New(t)

	mockGoDir := newMockGoDir()
	mockGoDir.PathOutput.ret0 <- "/some/path"
	mockGoDir.PackagesOutput.ret0 <- map[string]*ast.Package{
		"foo": {
			Name: "foo",
			Files: map[string]*ast.File{
				"foo.go": parse(expect, "type Foo interface{}"),
			},
		},
		"foo_test": {
			Name: "foo_test",
			Files: map[string]*ast.File{
				"foo_test.go": parse(expect, "type Bar interface{}"),
			},
		},
	}
	found := types.Load(mockGoDir)
	expect(found).To.Have.Len(1)
	expect(found[0].Len()).To.Equal(1)
	expect(found[0].Package()).To.Equal("foo")
	expect(found[0].TestPackage()).To.Equal("foo_test")
}

func TestLoad_TestFilesInNonTestPackage(t *testing.T) {
	expect := expect.New(t)

	mockGoDir := newMockGoDir()
	mockGoDir.PathOutput.ret0 <- "/some/path"
	mockGoDir.PackagesOutput.ret0 <- map[string]*ast.Package{
		"foo": {
			Name: "foo",
			Files: map[string]*ast.File{
				"foo.go":      parse(expect, "type Foo interface{}"),
				"foo_test.go": parse(expect, "type Bar interface{}"),
			},
		},
	}
	found := types.Load(mockGoDir)
	expect(found).To.Have.Len(1)
	expect(found[0].Len()).To.Equal(1)
	expect(found[0].Package()).To.Equal("foo")
	expect(found[0].TestPackage()).To.Equal("foo")
}

func TestFilter(t *testing.T) {
	expect := expect.New(t)

	mockGoDir := newMockGoDir()
	mockGoDir.PathOutput.ret0 <- "/some/path"
	mockGoDir.PackagesOutput.ret0 <- map[string]*ast.Package{
		"foo": {
			Name: "foo",
			Files: map[string]*ast.File{
				"foo.go": parse(expect, `
    type Foo interface {}
    type Bar interface {}
    type FooBar interface {}
    type BarFoo interface {}
    `),
			},
		},
	}
	found := types.Load(mockGoDir)
	expect(found).To.Have.Len(1)
	expect(found[0].Len()).To.Equal(4)

	notFiltered := found.Filter()
	expect(notFiltered).To.Have.Len(1)
	expect(notFiltered[0].Len()).To.Equal(4)

	foos := found.Filter("Foo")
	expect(foos).To.Have.Len(1)
	expect(foos[0].Len()).To.Equal(1)
	expect(foos[0].ExportedTypes()[0].Name.String()).To.Equal("Foo")

	fooPrefixes := found.Filter("Foo.*")
	expect(fooPrefixes).To.Have.Len(1)
	expect(fooPrefixes[0].Len()).To.Equal(2)
	expectNamesToMatch(expect, fooPrefixes[0].ExportedTypes(), "Foo", "FooBar")

	fooPostfixes := found.Filter(".*Foo")
	expect(fooPostfixes).To.Have.Len(1)
	expect(fooPostfixes[0].Len()).To.Equal(2)
	expectNamesToMatch(expect, fooPostfixes[0].ExportedTypes(), "Foo", "BarFoo")

	fooContainers := found.Filter("Foo.*", ".*Foo")
	expect(fooContainers).To.Have.Len(1)
	expect(fooContainers[0].Len()).To.Equal(3)
	expectNamesToMatch(expect, fooContainers[0].ExportedTypes(), "Foo", "FooBar", "BarFoo")
}

func expectNamesToMatch(expect func(interface{}) *expect.Expect, list []*ast.TypeSpec, names ...string) {
	listNames := make(map[string]struct{}, len(list))
	for _, spec := range list {
		listNames[spec.Name.String()] = struct{}{}
	}
	expectedNames := make(map[string]struct{}, len(names))
	for _, name := range names {
		expectedNames[name] = struct{}{}
	}
	expect(listNames).To.Equal(expectedNames)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"context"
	"crypto/rand"
	"flag"
	"fmt"
	"os"

	"github.com/libp2p/go-libp2p"
	"github.com/libp2p/go-libp2p/core/crypto"
	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/protocol"

	"github.com/multiformats/go-multiaddr"
)

func handleStream(stream network.Stream) {
	fmt.Println("Got a new stream!")

	// Create a buffer stream for non blocking read and write.
	rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))

	go readData(rw)
	go writeData(rw)

	// 'stream' will stay open until you close it (or the other side closes it).
}

func readData(rw *bufio.ReadWriter) {
	for {
		str, err := rw.ReadString('\n')
		if err != nil {
			fmt.Println("Error reading from buffer")
			panic(err)
		}

		if str == "" {
			return
		}
		if str != "\n" {
			// Green console colour: 	\x1b[32m
			// Reset console colour: 	\x1b[0m
			fmt.Printf("\x1b[32m%s\x1b[0m> ", str)
		}

	}
}

func writeData(rw *bufio.ReadWriter) {
	stdReader := bufio.NewReader(os.Stdin)

	for {
		fmt.Print("> ")
		sendData, err := stdReader.ReadString('\n')
		if err != nil {
			fmt.Println("Error reading from stdin")
			panic(err)
		}

		_, err = rw.WriteString(fmt.Sprintf("%s\n", sendData))
		if err != nil {
			fmt.Println("Error writing to buffer")
			panic(err)
		}
		err = rw.Flush()
		if err != nil {
			fmt.Println("Error flushing buffer")
			panic(err)
		}
	}
}

func main() {
	help := flag.Bool("help", false, "Display Help")
	cfg := parseFlags()

	if *help {
		fmt.Printf("Simple example for peer discovery using mDNS. mDNS is great when you have multiple peers in local LAN.")
		fmt.Printf("Usage: \n   Run './chat-with-mdns'\nor Run './chat-with-mdns -host [host] -port [port] -rendezvous [string] -pid [proto ID]'\n")

		os.Exit(0)
	}

	fmt.Printf("[*] Listening on: %s with port: %d\n", cfg.listenHost, cfg.listenPort)

	ctx := context.Background()
	r := rand.Reader

	// Creates a new RSA key pair for this host.
	prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r)
	if err != nil {
		panic(err)
	}

	// 0.0.0.0 will listen on any interface device.
	sourceMultiAddr, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d", cfg.listenHost, cfg.listenPort))

	// libp2p.New constructs a new libp2p Host.
	// Other options can be added here.
	host, err := libp2p.New(
		libp2p.ListenAddrs(sourceMultiAddr),
		libp2p.Identity(prvKey),
	)
	if err != nil {
		panic(err)
	}

	// Set a function as stream handler.
	// This function is called when a peer initiates a connection and starts a stream with this peer.
	host.SetStreamHandler(protocol.ID(cfg.ProtocolID), handleStream)

	fmt.Printf("\n[*] Your Multiaddress Is: /ip4/%s/tcp/%v/p2p/%s\n", cfg.listenHost, cfg.listenPort, host.ID().Pretty())

	peerChan := initMDNS(host, cfg.RendezvousString)

	peer := <-peerChan // will block untill we discover a peer
	fmt.Println("Found peer:", peer, ", connecting")

	if err := host.Connect(ctx, peer); err != nil {
		fmt.Println("Connection failed:", err)
	}

	// open a stream, this stream will be handled by handleStream other end
	stream, err := host.NewStream(ctx, peer.ID, protocol.ID(cfg.ProtocolID))

	if err != nil {
		fmt.Println("Stream open failed", err)
	} else {
		rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))

		go writeData(rw)
		go readData(rw)
		fmt.Println("Connected to:", peer)
	}

	select {} // wait here
}
<commit_msg>examples: connect to all peers in example mdns chat app (#1798)<commit_after>package main

import (
	"bufio"
	"context"
	"crypto/rand"
	"flag"
	"fmt"
	"os"

	"github.com/libp2p/go-libp2p"
	"github.com/libp2p/go-libp2p/core/crypto"
	"github.com/libp2p/go-libp2p/core/network"
	"github.com/libp2p/go-libp2p/core/protocol"

	"github.com/multiformats/go-multiaddr"
)

func handleStream(stream network.Stream) {
	fmt.Println("Got a new stream!")

	// Create a buffer stream for non blocking read and write.
	rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))

	go readData(rw)
	go writeData(rw)

	// 'stream' will stay open until you close it (or the other side closes it).
}

func readData(rw *bufio.ReadWriter) {
	for {
		str, err := rw.ReadString('\n')
		if err != nil {
			fmt.Println("Error reading from buffer")
			panic(err)
		}

		if str == "" {
			return
		}
		if str != "\n" {
			// Green console colour: 	\x1b[32m
			// Reset console colour: 	\x1b[0m
			fmt.Printf("\x1b[32m%s\x1b[0m> ", str)
		}

	}
}

func writeData(rw *bufio.ReadWriter) {
	stdReader := bufio.NewReader(os.Stdin)

	for {
		fmt.Print("> ")
		sendData, err := stdReader.ReadString('\n')
		if err != nil {
			fmt.Println("Error reading from stdin")
			panic(err)
		}

		_, err = rw.WriteString(fmt.Sprintf("%s\n", sendData))
		if err != nil {
			fmt.Println("Error writing to buffer")
			panic(err)
		}
		err = rw.Flush()
		if err != nil {
			fmt.Println("Error flushing buffer")
			panic(err)
		}
	}
}

func main() {
	help := flag.Bool("help", false, "Display Help")
	cfg := parseFlags()

	if *help {
		fmt.Printf("Simple example for peer discovery using mDNS. mDNS is great when you have multiple peers in local LAN.")
		fmt.Printf("Usage: \n   Run './chat-with-mdns'\nor Run './chat-with-mdns -host [host] -port [port] -rendezvous [string] -pid [proto ID]'\n")

		os.Exit(0)
	}

	fmt.Printf("[*] Listening on: %s with port: %d\n", cfg.listenHost, cfg.listenPort)

	ctx := context.Background()
	r := rand.Reader

	// Creates a new RSA key pair for this host.
	prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r)
	if err != nil {
		panic(err)
	}

	// 0.0.0.0 will listen on any interface device.
	sourceMultiAddr, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d", cfg.listenHost, cfg.listenPort))

	// libp2p.New constructs a new libp2p Host.
	// Other options can be added here.
	host, err := libp2p.New(
		libp2p.ListenAddrs(sourceMultiAddr),
		libp2p.Identity(prvKey),
	)
	if err != nil {
		panic(err)
	}

	// Set a function as stream handler.
	// This function is called when a peer initiates a connection and starts a stream with this peer.
	host.SetStreamHandler(protocol.ID(cfg.ProtocolID), handleStream)

	fmt.Printf("\n[*] Your Multiaddress Is: /ip4/%s/tcp/%v/p2p/%s\n", cfg.listenHost, cfg.listenPort, host.ID().Pretty())

	peerChan := initMDNS(host, cfg.RendezvousString)
	for { // allows multiple peers to join
		peer := <-peerChan // will block untill we discover a peer
		fmt.Println("Found peer:", peer, ", connecting")

		if err := host.Connect(ctx, peer); err != nil {
			fmt.Println("Connection failed:", err)
			continue
		}

		// open a stream, this stream will be handled by handleStream other end
		stream, err := host.NewStream(ctx, peer.ID, protocol.ID(cfg.ProtocolID))

		if err != nil {
			fmt.Println("Stream open failed", err)
		} else {
			rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))

			go writeData(rw)
			go readData(rw)
			fmt.Println("Connected to:", peer)
		}
	}
}
<|endoftext|>


<commit_before>package error

import "math"

// used in CONNECTION_CLOSE frame
type TransportError uint16

const (
	NoError TransportError = iota
	InternalError
	ServerBusy
	FlowControlError
	StreamIDError
	StreamStateError
	FinalOffsetError
	FrameEncodingError
	TransportParameterError
	VersionNegotiationError
	ProtocolViolation
	InvalidMigration = 0xc

	CryptoError = 0x100 // 0x1XX, XX is reserved for carrying error codes specific to the cryptographic handshake
)

func (e TransportError) Error() string {
	if e >= CryptoError {
		// TODO: solve import cycle by separating file of FrameType implementation
		return "CryptoError: " // + quiclatest.FrameType(uint16(e)&0xff).String()
	}
	return []string{
		"NoError",
		"InternalError",
		"ServerBusy",
		"FlowControlError",
		"StreamIDError",
		"StreamStateError",
		"FinalOffsetError",
		"FrameEncodingError",
		"TransportParameterError",
		"VersionNegotiationError",
		"ProtocolViolation",
		"_",
		"InvalidMigration",
	}[e]
}

// only 0 is reserved for STOPPING
type ApplicationError uint16

const (
	Stopping             ApplicationError = iota
	ApplicationErrorTest ApplicationError = math.MaxUint16
)

func (e ApplicationError) Error() string {
	if e == ApplicationErrorTest {
		return "Application Error Test"
	}
	return []string{
		"Stopping",
	}[e]
}
<commit_msg>fix error type<commit_after>package error

import "math"

// used in CONNECTION_CLOSE frame
type TransportError uint16

const (
	NoError TransportError = iota
	InternalError
	ServerBusy
	FlowControlError
	StreamIDError
	StreamStateError
	FinalOffsetError
	FrameEncodingError
	TransportParameterError
	VersionNegotiationError
	ProtocolViolation
	InvalidMigration TransportError = 0xc

	CryptoError = 0x100 // 0x1XX, XX is reserved for carrying error codes specific to the cryptographic handshake
)

func (e TransportError) Error() string {
	if e >= CryptoError {
		// TODO: solve import cycle by separating file of FrameType implementation
		return "CryptoError: " // + quiclatest.FrameType(uint16(e)&0xff).String()
	}
	return []string{
		"NoError",
		"InternalError",
		"ServerBusy",
		"FlowControlError",
		"StreamIDError",
		"StreamStateError",
		"FinalOffsetError",
		"FrameEncodingError",
		"TransportParameterError",
		"VersionNegotiationError",
		"ProtocolViolation",
		"_",
		"InvalidMigration",
	}[e]
}

// only 0 is reserved for STOPPING
type ApplicationError uint16

const (
	Stopping             ApplicationError = iota
	ApplicationErrorTest ApplicationError = math.MaxUint16
)

func (e ApplicationError) Error() string {
	if e == ApplicationErrorTest {
		return "Application Error Test"
	}
	return []string{
		"Stopping",
	}[e]
}
<|endoftext|>


<commit_before>//  Copyright 2015 Walter Schulze
//
//  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 debug

import (
	"fmt"
	"github.com/katydid/katydid/serialize"
	"io"
	"math/rand"
	"strings"
	"time"
)

func getValue(parser serialize.Parser) interface{} {
	var v interface{}
	var err error
	v, err = parser.Int()
	if err == nil {
		return v
	}
	v, err = parser.Uint()
	if err == nil {
		return v
	}
	v, err = parser.Double()
	if err == nil {
		return v
	}
	v, err = parser.Bool()
	if err == nil {
		return v
	}
	v, err = parser.String()
	if err == nil {
		return v
	}
	v, err = parser.Bytes()
	if err == nil {
		return v
	}
	return nil
}

type Node struct {
	Label    string
	Children Nodes
}

func (this Node) String() string {
	if len(this.Children) == 0 {
		return this.Label
	}
	return this.Label + ":" + this.Children.String()
}

func (this Node) Equal(that Node) bool {
	if this.Label != that.Label {
		return false
	}
	if !this.Children.Equal(that.Children) {
		return false
	}
	return true
}

type Nodes []Node

func (this Nodes) String() string {
	ss := make([]string, len(this))
	for i := range this {
		ss[i] = this[i].String()
	}
	return "{" + strings.Join(ss, ",") + "}"
}

func (this Nodes) Equal(that Nodes) bool {
	if len(this) != len(that) {
		return false
	}
	for i := range this {
		if !this[i].Equal(that[i]) {
			return false
		}
	}
	return true
}

func Walk(parser serialize.Parser) Nodes {
	a := make(Nodes, 0)
	for {
		if err := parser.Next(); err != nil {
			if err == io.EOF {
				break
			} else {
				panic(err)
			}
		}
		value := getValue(parser)
		if parser.IsLeaf() {
			a = append(a, Node{fmt.Sprintf("%v", value), nil})
		} else {
			name := fmt.Sprintf("%v", value)
			parser.Down()
			v := Walk(parser)
			parser.Up()
			a = append(a, Node{name, v})
		}
	}
	return a
}

func NewRand() Rand {
	return rand.New(rand.NewSource(time.Now().UnixNano()))
}

type Rand interface {
	Intn(n int) int
}

func RandomWalk(parser serialize.Parser, r Rand, next, down int) Nodes {
	a := make(Nodes, 0)
	for {
		if r.Intn(next) == 0 {
			break
		}
		if err := parser.Next(); err != nil {
			if err == io.EOF {
				break
			} else {
				panic(err)
			}
		}
		value := getValue(parser)
		if parser.IsLeaf() {
			a = append(a, Node{fmt.Sprintf("%#v", value), nil})
		} else {
			name := fmt.Sprintf("%#v", value)
			var v Nodes
			if r.Intn(down) != 0 {
				parser.Down()
				v = RandomWalk(parser, r, next, down)
				parser.Up()
			}
			a = append(a, Node{name, v})
		}
	}
	return a
}
<commit_msg>string walk<commit_after>//  Copyright 2015 Walter Schulze
//
//  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 debug

import (
	"fmt"
	"github.com/katydid/katydid/serialize"
	"io"
	"math/rand"
	"strings"
	"time"
)

func getValue(parser serialize.Parser) interface{} {
	var v interface{}
	var err error
	v, err = parser.Int()
	if err == nil {
		return v
	}
	v, err = parser.Uint()
	if err == nil {
		return v
	}
	v, err = parser.Double()
	if err == nil {
		return v
	}
	v, err = parser.Bool()
	if err == nil {
		return v
	}
	v, err = parser.String()
	if err == nil {
		return v
	}
	v, err = parser.Bytes()
	if err == nil {
		return v
	}
	return nil
}

type Node struct {
	Label    string
	Children Nodes
}

func (this Node) String() string {
	if len(this.Children) == 0 {
		return this.Label
	}
	return this.Label + ":" + this.Children.String()
}

func (this Node) Equal(that Node) bool {
	if this.Label != that.Label {
		return false
	}
	if !this.Children.Equal(that.Children) {
		return false
	}
	return true
}

type Nodes []Node

func (this Nodes) String() string {
	ss := make([]string, len(this))
	for i := range this {
		ss[i] = this[i].String()
	}
	return "{" + strings.Join(ss, ",") + "}"
}

func (this Nodes) Equal(that Nodes) bool {
	if len(this) != len(that) {
		return false
	}
	for i := range this {
		if !this[i].Equal(that[i]) {
			return false
		}
	}
	return true
}

func Walk(parser serialize.Parser) Nodes {
	a := make(Nodes, 0)
	for {
		if err := parser.Next(); err != nil {
			if err == io.EOF {
				break
			} else {
				panic(err)
			}
		}
		value := getValue(parser)
		if parser.IsLeaf() {
			a = append(a, Node{fmt.Sprintf("%v", value), nil})
		} else {
			name := fmt.Sprintf("%v", value)
			parser.Down()
			v := Walk(parser)
			parser.Up()
			a = append(a, Node{name, v})
		}
	}
	return a
}

func StringWalk(parser serialize.Parser) Nodes {
	a := make(Nodes, 0)
	for {
		if err := parser.Next(); err != nil {
			if err == io.EOF {
				break
			} else {
				panic(err)
			}
		}
		if parser.IsLeaf() {
			value := getValue(parser)
			a = append(a, Node{fmt.Sprintf("%v", value), nil})
		} else {
			var name string
			index, err := parser.Int()
			if err == nil {
				name = fmt.Sprintf("%d", index)
			} else {
				name, err = parser.String()
				if err != nil {
					panic(err)
				}
			}
			parser.Down()
			v := StringWalk(parser)
			parser.Up()
			a = append(a, Node{name, v})
		}
	}
	return a
}

func NewRand() Rand {
	return rand.New(rand.NewSource(time.Now().UnixNano()))
}

type Rand interface {
	Intn(n int) int
}

func RandomWalk(parser serialize.Parser, r Rand, next, down int) Nodes {
	a := make(Nodes, 0)
	for {
		if r.Intn(next) == 0 {
			break
		}
		if err := parser.Next(); err != nil {
			if err == io.EOF {
				break
			} else {
				panic(err)
			}
		}
		value := getValue(parser)
		if parser.IsLeaf() {
			a = append(a, Node{fmt.Sprintf("%#v", value), nil})
		} else {
			name := fmt.Sprintf("%#v", value)
			var v Nodes
			if r.Intn(down) != 0 {
				parser.Down()
				v = RandomWalk(parser, r, next, down)
				parser.Up()
			}
			a = append(a, Node{name, v})
		}
	}
	return a
}
<|endoftext|>


<commit_before>package qtype

import (
	"math"

	"github.com/ami-GS/gQUIC/latest/utils"
)

type PacketNumber uint32

const InitialPacketNumber PacketNumber = 0

const PacketNumberIncreaseSize = 1

// TODO: will be deprecated
const (
	InitialPacketNumberMin = 0
	// 2^32-1025
	InitialPacketNumberMax = 4294966271
)

func (pn PacketNumber) GetEncoded() uint32 {
	switch {
	case 0 <= pn && pn <= 127:
		return uint32(pn)
	case 0 <= pn && pn <= 16383:
		return uint32(pn) | 0x8000
	case 0 <= pn && pn <= 1073741823:
		return uint32(pn) | 0xC0000000
	default:
		return 0
	}
	panic("")
}

func (pn PacketNumber) GetByteLen() int {
	switch {
	case 0 <= pn && pn <= 127:
		return 1
	case 0 <= pn && pn <= 16383:
		return 2
	case 0 <= pn && pn <= 1073741823:
		return 4
	default:
		return 0
	}
	panic("")
}

func (pn PacketNumber) PutWire(wire []byte) int {
	byteLen := pn.GetByteLen()
	utils.MyPutUint32(wire, uint32(pn.GetEncoded()), byteLen)
	return byteLen
}

func DecodePacketNumber(data []byte) PacketNumber {
	flag := byte(0)
	if data[0]>>7 != 0 {
		flag = (data[0] & 0xc0) >> 6
	}
	byteLen := int(math.Pow(2, float64(flag)))
	val := PacketNumber(utils.MyUint32(data, byteLen))
	switch byteLen {
	case 1:
		return val
	case 2:
		return val & 0x3fff
	case 4:
		return val & 0x3fffffff
	}
	panic("")
}

func (pn *PacketNumber) Increase() PacketNumber {
	*pn += PacketNumberIncreaseSize
	return *pn
}
<commit_msg>fix packet number decoding issue<commit_after>package qtype

import (
	"math"

	"github.com/ami-GS/gQUIC/latest/utils"
)

type PacketNumber uint32

const InitialPacketNumber PacketNumber = 0

const PacketNumberIncreaseSize = 1

// TODO: will be deprecated
const (
	InitialPacketNumberMin = 0
	// 2^32-1025
	InitialPacketNumberMax = 4294966271
)

func (pn PacketNumber) GetEncoded() uint32 {
	switch {
	case 0 <= pn && pn <= 127:
		return uint32(pn)
	case 0 <= pn && pn <= 16383:
		return uint32(pn) | 0x8000
	case 0 <= pn && pn <= 1073741823:
		return uint32(pn) | 0xC0000000
	default:
		return 0
	}
	panic("")
}

func (pn PacketNumber) GetByteLen() int {
	switch {
	case 0 <= pn && pn <= 127:
		return 1
	case 0 <= pn && pn <= 16383:
		return 2
	case 0 <= pn && pn <= 1073741823:
		return 4
	default:
		return 0
	}
	panic("")
}

func (pn PacketNumber) PutWire(wire []byte) int {
	byteLen := pn.GetByteLen()
	utils.MyPutUint32(wire, uint32(pn.GetEncoded()), byteLen)
	return byteLen
}

func DecodePacketNumber(data []byte) PacketNumber {
	flag := byte(0)
	if data[0]>>7 != 0 {
		flag = ((data[0] & 0xc0) >> 6) - 1
	}
	byteLen := int(math.Pow(2, float64(flag)))
	val := PacketNumber(utils.MyUint32(data, byteLen))
	switch byteLen {
	case 1:
		return val
	case 2:
		return val & 0x3fff
	case 4:
		return val & 0x3fffffff
	}
	panic("")
}

func (pn *PacketNumber) Increase() PacketNumber {
	*pn += PacketNumberIncreaseSize
	return *pn
}
<|endoftext|>


<commit_before>// Copyright Istio Authors
//
// 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 main

import (
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"k8s.io/utils/env"

	testenv "istio.io/istio/pkg/test/env"
	"istio.io/istio/pkg/util/sets"
	"istio.io/pkg/log"
)

// Types mirrored from https://github.com/docker/buildx/blob/master/bake/bake.go
type Group struct {
	Targets []string `json:"targets" hcl:"targets"`
}

type BakeFile struct {
	Target map[string]Target `json:"target,omitempty"`
	Group  map[string]Group  `json:"group,omitempty"`
}

type Target struct {
	Context          *string           `json:"context,omitempty" hcl:"context,optional"`
	Dockerfile       *string           `json:"dockerfile,omitempty" hcl:"dockerfile,optional"`
	DockerfileInline *string           `json:"dockerfile-inline,omitempty" hcl:"dockerfile-inline,optional"`
	Args             map[string]string `json:"args,omitempty" hcl:"args,optional"`
	Labels           map[string]string `json:"labels,omitempty" hcl:"labels,optional"`
	Tags             []string          `json:"tags,omitempty" hcl:"tags,optional"`
	CacheFrom        []string          `json:"cache-from,omitempty"  hcl:"cache-from,optional"`
	CacheTo          []string          `json:"cache-to,omitempty"  hcl:"cache-to,optional"`
	Target           *string           `json:"target,omitempty" hcl:"target,optional"`
	Secrets          []string          `json:"secret,omitempty" hcl:"secret,optional"`
	SSH              []string          `json:"ssh,omitempty" hcl:"ssh,optional"`
	Platforms        []string          `json:"platforms,omitempty" hcl:"platforms,optional"`
	Outputs          []string          `json:"output,omitempty" hcl:"output,optional"`
	Pull             *bool             `json:"pull,omitempty" hcl:"pull,optional"`
	NoCache          *bool             `json:"no-cache,omitempty" hcl:"no-cache,optional"`
}

type Args struct {
	Push          bool
	Save          bool
	Builder       string
	KindLoad      bool
	NoClobber     bool
	NoCache       bool
	Targets       []string
	Variants      []string
	Architectures []string
	BaseVersion   string
	ProxyVersion  string
	IstioVersion  string
	Tags          []string
	Hubs          []string

	// Plan describes the build plan, read from file
	Plan BuildPlan
}

func (a Args) String() string {
	var b strings.Builder
	b.WriteString("Push:          " + fmt.Sprint(a.Push) + "\n")
	b.WriteString("Save:          " + fmt.Sprint(a.Save) + "\n")
	b.WriteString("NoClobber:     " + fmt.Sprint(a.NoClobber) + "\n")
	b.WriteString("NoCache:       " + fmt.Sprint(a.NoCache) + "\n")
	b.WriteString("Targets:       " + fmt.Sprint(a.Targets) + "\n")
	b.WriteString("Variants:      " + fmt.Sprint(a.Variants) + "\n")
	b.WriteString("Architectures: " + fmt.Sprint(a.Architectures) + "\n")
	b.WriteString("BaseVersion:   " + fmt.Sprint(a.BaseVersion) + "\n")
	b.WriteString("ProxyVersion:  " + fmt.Sprint(a.ProxyVersion) + "\n")
	b.WriteString("IstioVersion:  " + fmt.Sprint(a.IstioVersion) + "\n")
	b.WriteString("Tags:          " + fmt.Sprint(a.Tags) + "\n")
	b.WriteString("Hubs:          " + fmt.Sprint(a.Hubs) + "\n")
	b.WriteString("Builder:       " + fmt.Sprint(a.Builder) + "\n")
	return b.String()
}

type ImagePlan struct {
	// Name of the image. For example, "pilot"
	Name string `json:"name"`
	// Dockerfile path to build from
	Dockerfile string `json:"dockerfile"`
	// Files list files that are copied as-is into the image
	Files []string `json:"files"`
	// Targets list make targets that are ran and then copied into the image
	Targets []string `json:"targets"`
	// Base indicates if this is a base image or not
	Base bool `json:"base"`
}

func (p ImagePlan) Dependencies() []string {
	v := []string{p.Dockerfile}
	v = append(v, p.Files...)
	v = append(v, p.Targets...)
	return v
}

type BuildPlan struct {
	Images []ImagePlan `json:"images"`
}

func (p BuildPlan) Targets() []string {
	tgts := sets.New()
	for _, img := range p.Images {
		tgts.InsertAll(img.Targets...)
	}
	return tgts.SortedList()
}

func (p BuildPlan) Find(n string) ImagePlan {
	for _, i := range p.Images {
		if i.Name == n {
			return i
		}
	}
	panic("couldn't find target " + n)
}

// Define variants, which control the base image of an image.
// Tags will have the variant append (like 1.0-distroless).
// The DefaultVariant is a special variant that has no explicit tag (like 1.0); it
// is not a unique variant though. Currently, it represents DebugVariant.
// If both DebugVariant and DefaultVariant are built, there will be a single build but multiple tags
const (
	// PrimaryVariant is the variant that DefaultVariant actually builds
	PrimaryVariant = DebugVariant

	DefaultVariant    = "default"
	DebugVariant      = "debug"
	DistrolessVariant = "distroless"
)

const (
	CraneBuilder  = "crane"
	DockerBuilder = "docker"
)

func DefaultArgs() Args {
	// By default, we build all targets
	var targets []string
	_, nonBaseImages, err := ReadPlanTargets()
	if err == nil {
		targets = nonBaseImages
	}
	if legacy, f := os.LookupEnv("DOCKER_TARGETS"); f {
		// Allow env var config. It is a string separated list like "docker.pilot docker.proxy"
		targets = []string{}
		for _, v := range strings.Split(legacy, " ") {
			if v == "" {
				continue
			}
			targets = append(targets, strings.TrimPrefix(v, "docker."))
		}
	}
	pv, err := testenv.ReadProxySHA()
	if err != nil {
		log.Warnf("failed to read proxy sha")
		pv = "unknown"
	}
	variants := []string{DefaultVariant}
	if legacy, f := os.LookupEnv("DOCKER_BUILD_VARIANTS"); f {
		variants = strings.Split(legacy, " ")
	}

	if os.Getenv("INCLUDE_UNTAGGED_DEFAULT") == "true" {
		// This legacy env var was to workaround the old build logic not being very smart
		// In the new builder, we automagically detect this. So just insert the 'default' variant
		cur := sets.New(variants...)
		cur.Insert(DefaultVariant)
		variants = cur.SortedList()
	}

	arch := []string{"linux/amd64"}
	if legacy, f := os.LookupEnv("DOCKER_ARCHITECTURES"); f {
		arch = strings.Split(legacy, ",")
	}

	hub := []string{env.GetString("HUB", "localhost:5000")}
	if hubs, f := os.LookupEnv("HUBS"); f {
		hub = strings.Split(hubs, " ")
	}
	tag := []string{env.GetString("TAG", "latest")}
	if tags, f := os.LookupEnv("TAGS"); f {
		tag = strings.Split(tags, " ")
	}

	builder := DockerBuilder
	if b, f := os.LookupEnv("ISTIO_DOCKER_BUILDER"); f {
		builder = b
	}

	return Args{
		Push:          false,
		Save:          false,
		NoCache:       false,
		Hubs:          hub,
		Tags:          tag,
		BaseVersion:   fetchBaseVersion(),
		IstioVersion:  fetchIstioVersion(),
		ProxyVersion:  pv,
		Architectures: arch,
		Targets:       targets,
		Variants:      variants,
		Builder:       builder,
	}
}

var (
	globalArgs = DefaultArgs()
	version    = false
)

var baseVersionRegexp = regexp.MustCompile(`BASE_VERSION \?= (.*)`)

func fetchBaseVersion() string {
	if b, f := os.LookupEnv("BASE_VERSION"); f {
		return b
	}
	b, err := os.ReadFile(filepath.Join(testenv.IstioSrc, "Makefile.core.mk"))
	if err != nil {
		log.Fatalf("failed to read file: %v", err)
		return "unknown"
	}
	match := baseVersionRegexp.FindSubmatch(b)
	if len(match) < 2 {
		log.Fatalf("failed to find match")
		return "unknown"
	}
	return string(match[1])
}

var istioVersionRegexp = regexp.MustCompile(`VERSION \?= (.*)`)

func fetchIstioVersion() string {
	if b, f := os.LookupEnv("VERSION"); f {
		return b
	}
	b, err := os.ReadFile(filepath.Join(testenv.IstioSrc, "Makefile.core.mk"))
	if err != nil {
		log.Fatalf("failed to read file: %v", err)
		return "unknown"
	}
	match := istioVersionRegexp.FindSubmatch(b)
	if len(match) < 2 {
		log.Fatalf("failed to find match")
		return "unknown"
	}
	return string(match[1])
}
<commit_msg>docker: always run `make init` (#38645)<commit_after>// Copyright Istio Authors
//
// 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 main

import (
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"k8s.io/utils/env"

	testenv "istio.io/istio/pkg/test/env"
	"istio.io/istio/pkg/util/sets"
	"istio.io/pkg/log"
)

// Types mirrored from https://github.com/docker/buildx/blob/master/bake/bake.go
type Group struct {
	Targets []string `json:"targets" hcl:"targets"`
}

type BakeFile struct {
	Target map[string]Target `json:"target,omitempty"`
	Group  map[string]Group  `json:"group,omitempty"`
}

type Target struct {
	Context          *string           `json:"context,omitempty" hcl:"context,optional"`
	Dockerfile       *string           `json:"dockerfile,omitempty" hcl:"dockerfile,optional"`
	DockerfileInline *string           `json:"dockerfile-inline,omitempty" hcl:"dockerfile-inline,optional"`
	Args             map[string]string `json:"args,omitempty" hcl:"args,optional"`
	Labels           map[string]string `json:"labels,omitempty" hcl:"labels,optional"`
	Tags             []string          `json:"tags,omitempty" hcl:"tags,optional"`
	CacheFrom        []string          `json:"cache-from,omitempty"  hcl:"cache-from,optional"`
	CacheTo          []string          `json:"cache-to,omitempty"  hcl:"cache-to,optional"`
	Target           *string           `json:"target,omitempty" hcl:"target,optional"`
	Secrets          []string          `json:"secret,omitempty" hcl:"secret,optional"`
	SSH              []string          `json:"ssh,omitempty" hcl:"ssh,optional"`
	Platforms        []string          `json:"platforms,omitempty" hcl:"platforms,optional"`
	Outputs          []string          `json:"output,omitempty" hcl:"output,optional"`
	Pull             *bool             `json:"pull,omitempty" hcl:"pull,optional"`
	NoCache          *bool             `json:"no-cache,omitempty" hcl:"no-cache,optional"`
}

type Args struct {
	Push          bool
	Save          bool
	Builder       string
	KindLoad      bool
	NoClobber     bool
	NoCache       bool
	Targets       []string
	Variants      []string
	Architectures []string
	BaseVersion   string
	ProxyVersion  string
	IstioVersion  string
	Tags          []string
	Hubs          []string

	// Plan describes the build plan, read from file
	Plan BuildPlan
}

func (a Args) String() string {
	var b strings.Builder
	b.WriteString("Push:          " + fmt.Sprint(a.Push) + "\n")
	b.WriteString("Save:          " + fmt.Sprint(a.Save) + "\n")
	b.WriteString("NoClobber:     " + fmt.Sprint(a.NoClobber) + "\n")
	b.WriteString("NoCache:       " + fmt.Sprint(a.NoCache) + "\n")
	b.WriteString("Targets:       " + fmt.Sprint(a.Targets) + "\n")
	b.WriteString("Variants:      " + fmt.Sprint(a.Variants) + "\n")
	b.WriteString("Architectures: " + fmt.Sprint(a.Architectures) + "\n")
	b.WriteString("BaseVersion:   " + fmt.Sprint(a.BaseVersion) + "\n")
	b.WriteString("ProxyVersion:  " + fmt.Sprint(a.ProxyVersion) + "\n")
	b.WriteString("IstioVersion:  " + fmt.Sprint(a.IstioVersion) + "\n")
	b.WriteString("Tags:          " + fmt.Sprint(a.Tags) + "\n")
	b.WriteString("Hubs:          " + fmt.Sprint(a.Hubs) + "\n")
	b.WriteString("Builder:       " + fmt.Sprint(a.Builder) + "\n")
	return b.String()
}

type ImagePlan struct {
	// Name of the image. For example, "pilot"
	Name string `json:"name"`
	// Dockerfile path to build from
	Dockerfile string `json:"dockerfile"`
	// Files list files that are copied as-is into the image
	Files []string `json:"files"`
	// Targets list make targets that are ran and then copied into the image
	Targets []string `json:"targets"`
	// Base indicates if this is a base image or not
	Base bool `json:"base"`
}

func (p ImagePlan) Dependencies() []string {
	v := []string{p.Dockerfile}
	v = append(v, p.Files...)
	v = append(v, p.Targets...)
	return v
}

type BuildPlan struct {
	Images []ImagePlan `json:"images"`
}

func (p BuildPlan) Targets() []string {
	tgts := sets.New("init") // All targets depend on init
	for _, img := range p.Images {
		tgts.InsertAll(img.Targets...)
	}
	return tgts.SortedList()
}

func (p BuildPlan) Find(n string) ImagePlan {
	for _, i := range p.Images {
		if i.Name == n {
			return i
		}
	}
	panic("couldn't find target " + n)
}

// Define variants, which control the base image of an image.
// Tags will have the variant append (like 1.0-distroless).
// The DefaultVariant is a special variant that has no explicit tag (like 1.0); it
// is not a unique variant though. Currently, it represents DebugVariant.
// If both DebugVariant and DefaultVariant are built, there will be a single build but multiple tags
const (
	// PrimaryVariant is the variant that DefaultVariant actually builds
	PrimaryVariant = DebugVariant

	DefaultVariant    = "default"
	DebugVariant      = "debug"
	DistrolessVariant = "distroless"
)

const (
	CraneBuilder  = "crane"
	DockerBuilder = "docker"
)

func DefaultArgs() Args {
	// By default, we build all targets
	var targets []string
	_, nonBaseImages, err := ReadPlanTargets()
	if err == nil {
		targets = nonBaseImages
	}
	if legacy, f := os.LookupEnv("DOCKER_TARGETS"); f {
		// Allow env var config. It is a string separated list like "docker.pilot docker.proxy"
		targets = []string{}
		for _, v := range strings.Split(legacy, " ") {
			if v == "" {
				continue
			}
			targets = append(targets, strings.TrimPrefix(v, "docker."))
		}
	}
	pv, err := testenv.ReadProxySHA()
	if err != nil {
		log.Warnf("failed to read proxy sha")
		pv = "unknown"
	}
	variants := []string{DefaultVariant}
	if legacy, f := os.LookupEnv("DOCKER_BUILD_VARIANTS"); f {
		variants = strings.Split(legacy, " ")
	}

	if os.Getenv("INCLUDE_UNTAGGED_DEFAULT") == "true" {
		// This legacy env var was to workaround the old build logic not being very smart
		// In the new builder, we automagically detect this. So just insert the 'default' variant
		cur := sets.New(variants...)
		cur.Insert(DefaultVariant)
		variants = cur.SortedList()
	}

	arch := []string{"linux/amd64"}
	if legacy, f := os.LookupEnv("DOCKER_ARCHITECTURES"); f {
		arch = strings.Split(legacy, ",")
	}

	hub := []string{env.GetString("HUB", "localhost:5000")}
	if hubs, f := os.LookupEnv("HUBS"); f {
		hub = strings.Split(hubs, " ")
	}
	tag := []string{env.GetString("TAG", "latest")}
	if tags, f := os.LookupEnv("TAGS"); f {
		tag = strings.Split(tags, " ")
	}

	builder := DockerBuilder
	if b, f := os.LookupEnv("ISTIO_DOCKER_BUILDER"); f {
		builder = b
	}

	return Args{
		Push:          false,
		Save:          false,
		NoCache:       false,
		Hubs:          hub,
		Tags:          tag,
		BaseVersion:   fetchBaseVersion(),
		IstioVersion:  fetchIstioVersion(),
		ProxyVersion:  pv,
		Architectures: arch,
		Targets:       targets,
		Variants:      variants,
		Builder:       builder,
	}
}

var (
	globalArgs = DefaultArgs()
	version    = false
)

var baseVersionRegexp = regexp.MustCompile(`BASE_VERSION \?= (.*)`)

func fetchBaseVersion() string {
	if b, f := os.LookupEnv("BASE_VERSION"); f {
		return b
	}
	b, err := os.ReadFile(filepath.Join(testenv.IstioSrc, "Makefile.core.mk"))
	if err != nil {
		log.Fatalf("failed to read file: %v", err)
		return "unknown"
	}
	match := baseVersionRegexp.FindSubmatch(b)
	if len(match) < 2 {
		log.Fatalf("failed to find match")
		return "unknown"
	}
	return string(match[1])
}

var istioVersionRegexp = regexp.MustCompile(`VERSION \?= (.*)`)

func fetchIstioVersion() string {
	if b, f := os.LookupEnv("VERSION"); f {
		return b
	}
	b, err := os.ReadFile(filepath.Join(testenv.IstioSrc, "Makefile.core.mk"))
	if err != nil {
		log.Fatalf("failed to read file: %v", err)
		return "unknown"
	}
	match := istioVersionRegexp.FindSubmatch(b)
	if len(match) < 2 {
		log.Fatalf("failed to find match")
		return "unknown"
	}
	return string(match[1])
}
<|endoftext|>


<commit_before>package drone

type (
	// User represents a user account.
	User struct {
		ID     int64  `json:"id"`
		Login  string `json:"login"`
		Email  string `json:"email"`
		Avatar string `json:"avatar_url"`
		Active bool   `json:"active"`
		Admin  bool   `json:"admin"`
	}

	// Repo represents a repository.
	Repo struct {
		ID          int64  `json:"id,omitempty"`
		Owner       string `json:"owner"`
		Name        string `json:"name"`
		FullName    string `json:"full_name"`
		Avatar      string `json:"avatar_url,omitempty"`
		Link        string `json:"link_url,omitempty"`
		Kind        string `json:"scm,omitempty"`
		Clone       string `json:"clone_url,omitempty"`
		Branch      string `json:"default_branch,omitempty"`
		Timeout     int64  `json:"timeout,omitempty"`
		IsPrivate   bool   `json:"private,omitempty"`
		IsTrusted   bool   `json:"trusted"`
		IsStarred   bool   `json:"starred,omitempty"`
		IsGated     bool   `json:"gated"`
		AllowPull   bool   `json:"allow_pr"`
		AllowPush   bool   `json:"allow_push"`
		AllowDeploy bool   `json:"allow_deploys"`
		AllowTag    bool   `json:"allow_tags"`
		Config      string `json:"config_file"`
	}

	// RepoPatch defines a repository patch request.
	RepoPatch struct {
		Config      *string `json:"config_file,omitempty"`
		IsTrusted   *bool   `json:"trusted,omitempty"`
		IsGated     *bool   `json:"gated,omitempty"`
		Timeout     *int64  `json:"timeout,omitempty"`
		AllowPull   *bool   `json:"allow_pr,omitempty"`
		AllowPush   *bool   `json:"allow_push,omitempty"`
		AllowDeploy *bool   `json:"allow_deploy,omitempty"`
		AllowTag    *bool   `json:"allow_tag,omitempty"`
	}

	// Build defines a build object.
	Build struct {
		ID        int64   `json:"id"`
		Number    int     `json:"number"`
		Parent    int     `json:"parent"`
		Event     string  `json:"event"`
		Status    string  `json:"status"`
		Error     string  `json:"error"`
		Enqueued  int64   `json:"enqueued_at"`
		Created   int64   `json:"created_at"`
		Started   int64   `json:"started_at"`
		Finished  int64   `json:"finished_at"`
		Deploy    string  `json:"deploy_to"`
		Commit    string  `json:"commit"`
		Branch    string  `json:"branch"`
		Ref       string  `json:"ref"`
		Refspec   string  `json:"refspec"`
		Remote    string  `json:"remote"`
		Title     string  `json:"title"`
		Message   string  `json:"message"`
		Timestamp int64   `json:"timestamp"`
		Sender    string  `json:"sender"`
		Author    string  `json:"author"`
		Avatar    string  `json:"author_avatar"`
		Email     string  `json:"author_email"`
		Link      string  `json:"link_url"`
		Reviewer  string  `json:"reviewed_by"`
		Reviewed  int64   `json:"reviewed_at"`
		Procs     []*Proc `json:"procs,omitempty"`
	}

	// Proc represents a process in the build pipeline.
	Proc struct {
		ID       int64             `json:"id"`
		PID      int               `json:"pid"`
		PPID     int               `json:"ppid"`
		PGID     int               `json:"pgid"`
		Name     string            `json:"name"`
		State    string            `json:"state"`
		Error    string            `json:"error,omitempty"`
		ExitCode int               `json:"exit_code"`
		Started  int64             `json:"start_time,omitempty"`
		Stopped  int64             `json:"end_time,omitempty"`
		Machine  string            `json:"machine,omitempty"`
		Platform string            `json:"platform,omitempty"`
		Environ  map[string]string `json:"environ,omitempty"`
		Children []*Proc           `json:"children,omitempty"`
	}

	// Registry represents a docker registry with credentials.
	Registry struct {
		ID       int64  `json:"id"`
		Address  string `json:"address"`
		Username string `json:"username"`
		Password string `json:"password,omitempty"`
		Email    string `json:"email"`
		Token    string `json:"token"`
	}

	// Secret represents a secret variable, such as a password or token.
	Secret struct {
		ID     int64    `json:"id"`
		Name   string   `json:"name"`
		Value  string   `json:"value,omitempty"`
		Images []string `json:"image"`
		Events []string `json:"event"`
	}

	// Activity represents an item in the user's feed or timeline.
	Activity struct {
		Owner    string `json:"owner"`
		Name     string `json:"name"`
		FullName string `json:"full_name"`
		Number   int    `json:"number,omitempty"`
		Event    string `json:"event,omitempty"`
		Status   string `json:"status,omitempty"`
		Created  int64  `json:"created_at,omitempty"`
		Started  int64  `json:"started_at,omitempty"`
		Finished int64  `json:"finished_at,omitempty"`
		Commit   string `json:"commit,omitempty"`
		Branch   string `json:"branch,omitempty"`
		Ref      string `json:"ref,omitempty"`
		Refspec  string `json:"refspec,omitempty"`
		Remote   string `json:"remote,omitempty"`
		Title    string `json:"title,omitempty"`
		Message  string `json:"message,omitempty"`
		Author   string `json:"author,omitempty"`
		Avatar   string `json:"author_avatar,omitempty"`
		Email    string `json:"author_email,omitempty"`
	}
)
<commit_msg>add visibility to repo patch payload<commit_after>package drone

type (
	// User represents a user account.
	User struct {
		ID     int64  `json:"id"`
		Login  string `json:"login"`
		Email  string `json:"email"`
		Avatar string `json:"avatar_url"`
		Active bool   `json:"active"`
		Admin  bool   `json:"admin"`
	}

	// Repo represents a repository.
	Repo struct {
		ID          int64  `json:"id,omitempty"`
		Owner       string `json:"owner"`
		Name        string `json:"name"`
		FullName    string `json:"full_name"`
		Avatar      string `json:"avatar_url,omitempty"`
		Link        string `json:"link_url,omitempty"`
		Kind        string `json:"scm,omitempty"`
		Clone       string `json:"clone_url,omitempty"`
		Branch      string `json:"default_branch,omitempty"`
		Timeout     int64  `json:"timeout,omitempty"`
		Visibility  string `json:"visibility"`
		IsPrivate   bool   `json:"private,omitempty"`
		IsTrusted   bool   `json:"trusted"`
		IsStarred   bool   `json:"starred,omitempty"`
		IsGated     bool   `json:"gated"`
		AllowPull   bool   `json:"allow_pr"`
		AllowPush   bool   `json:"allow_push"`
		AllowDeploy bool   `json:"allow_deploys"`
		AllowTag    bool   `json:"allow_tags"`
		Config      string `json:"config_file"`
	}

	// RepoPatch defines a repository patch request.
	RepoPatch struct {
		Config      *string `json:"config_file,omitempty"`
		IsTrusted   *bool   `json:"trusted,omitempty"`
		IsGated     *bool   `json:"gated,omitempty"`
		Timeout     *int64  `json:"timeout,omitempty"`
		Visibility  *string `json:"visibility"`
		AllowPull   *bool   `json:"allow_pr,omitempty"`
		AllowPush   *bool   `json:"allow_push,omitempty"`
		AllowDeploy *bool   `json:"allow_deploy,omitempty"`
		AllowTag    *bool   `json:"allow_tag,omitempty"`
	}

	// Build defines a build object.
	Build struct {
		ID        int64   `json:"id"`
		Number    int     `json:"number"`
		Parent    int     `json:"parent"`
		Event     string  `json:"event"`
		Status    string  `json:"status"`
		Error     string  `json:"error"`
		Enqueued  int64   `json:"enqueued_at"`
		Created   int64   `json:"created_at"`
		Started   int64   `json:"started_at"`
		Finished  int64   `json:"finished_at"`
		Deploy    string  `json:"deploy_to"`
		Commit    string  `json:"commit"`
		Branch    string  `json:"branch"`
		Ref       string  `json:"ref"`
		Refspec   string  `json:"refspec"`
		Remote    string  `json:"remote"`
		Title     string  `json:"title"`
		Message   string  `json:"message"`
		Timestamp int64   `json:"timestamp"`
		Sender    string  `json:"sender"`
		Author    string  `json:"author"`
		Avatar    string  `json:"author_avatar"`
		Email     string  `json:"author_email"`
		Link      string  `json:"link_url"`
		Reviewer  string  `json:"reviewed_by"`
		Reviewed  int64   `json:"reviewed_at"`
		Procs     []*Proc `json:"procs,omitempty"`
	}

	// Proc represents a process in the build pipeline.
	Proc struct {
		ID       int64             `json:"id"`
		PID      int               `json:"pid"`
		PPID     int               `json:"ppid"`
		PGID     int               `json:"pgid"`
		Name     string            `json:"name"`
		State    string            `json:"state"`
		Error    string            `json:"error,omitempty"`
		ExitCode int               `json:"exit_code"`
		Started  int64             `json:"start_time,omitempty"`
		Stopped  int64             `json:"end_time,omitempty"`
		Machine  string            `json:"machine,omitempty"`
		Platform string            `json:"platform,omitempty"`
		Environ  map[string]string `json:"environ,omitempty"`
		Children []*Proc           `json:"children,omitempty"`
	}

	// Registry represents a docker registry with credentials.
	Registry struct {
		ID       int64  `json:"id"`
		Address  string `json:"address"`
		Username string `json:"username"`
		Password string `json:"password,omitempty"`
		Email    string `json:"email"`
		Token    string `json:"token"`
	}

	// Secret represents a secret variable, such as a password or token.
	Secret struct {
		ID     int64    `json:"id"`
		Name   string   `json:"name"`
		Value  string   `json:"value,omitempty"`
		Images []string `json:"image"`
		Events []string `json:"event"`
	}

	// Activity represents an item in the user's feed or timeline.
	Activity struct {
		Owner    string `json:"owner"`
		Name     string `json:"name"`
		FullName string `json:"full_name"`
		Number   int    `json:"number,omitempty"`
		Event    string `json:"event,omitempty"`
		Status   string `json:"status,omitempty"`
		Created  int64  `json:"created_at,omitempty"`
		Started  int64  `json:"started_at,omitempty"`
		Finished int64  `json:"finished_at,omitempty"`
		Commit   string `json:"commit,omitempty"`
		Branch   string `json:"branch,omitempty"`
		Ref      string `json:"ref,omitempty"`
		Refspec  string `json:"refspec,omitempty"`
		Remote   string `json:"remote,omitempty"`
		Title    string `json:"title,omitempty"`
		Message  string `json:"message,omitempty"`
		Author   string `json:"author,omitempty"`
		Avatar   string `json:"author_avatar,omitempty"`
		Email    string `json:"author_email,omitempty"`
	}
)
<|endoftext|>


<commit_before>package udp

import (
	"v2ray.com/core/common/buf"
	"v2ray.com/core/common/net"
)

// Payload represents a single UDP payload.
type Payload struct {
	Content             *buf.Buffer
	Source              net.Destination
	OriginalDestination net.Destination
}

type HubOption func(h *Hub)

func HubCapacity(cap int) HubOption {
	return func(h *Hub) {
		h.capacity = cap
	}
}

func HubReceiveOriginalDestination(r bool) HubOption {
	return func(h *Hub) {
		h.recvOrigDest = r
	}
}

type Hub struct {
	conn         *net.UDPConn
	cache        chan *Payload
	capacity     int
	recvOrigDest bool
}

func ListenUDP(address net.Address, port net.Port, options ...HubOption) (*Hub, error) {
	udpConn, err := net.ListenUDP("udp", &net.UDPAddr{
		IP:   address.IP(),
		Port: int(port),
	})
	if err != nil {
		return nil, err
	}
	newError("listening UDP on ", address, ":", port).WriteToLog()
	hub := &Hub{
		conn:         udpConn,
		capacity:     256,
		recvOrigDest: false,
	}
	for _, opt := range options {
		opt(hub)
	}

	hub.cache = make(chan *Payload, hub.capacity)

	if hub.recvOrigDest {
		rawConn, err := udpConn.SyscallConn()
		if err != nil {
			return nil, newError("failed to get fd").Base(err)
		}
		err = rawConn.Control(func(fd uintptr) {
			if err := SetOriginalDestOptions(int(fd)); err != nil {
				newError("failed to set socket options").Base(err).WriteToLog()
			}
		})
		if err != nil {
			return nil, newError("failed to control socket").Base(err)
		}
	}

	go hub.start()
	return hub, nil
}

// Close implements net.Listener.
func (h *Hub) Close() error {
	h.conn.Close()
	return nil
}

func (h *Hub) WriteTo(payload []byte, dest net.Destination) (int, error) {
	return h.conn.WriteToUDP(payload, &net.UDPAddr{
		IP:   dest.Address.IP(),
		Port: int(dest.Port),
	})
}

func (h *Hub) start() {
	c := h.cache
	defer close(c)

	oobBytes := make([]byte, 256)

	for {
		buffer := buf.New()
		var noob int
		var addr *net.UDPAddr
		err := buffer.AppendSupplier(func(b []byte) (int, error) {
			n, nb, _, a, e := ReadUDPMsg(h.conn, b, oobBytes)
			noob = nb
			addr = a
			return n, e
		})

		if err != nil {
			newError("failed to read UDP msg").Base(err).WriteToLog()
			buffer.Release()
			break
		}

		payload := &Payload{
			Content: buffer,
			Source:  net.UDPDestination(net.IPAddress(addr.IP), net.Port(addr.Port)),
		}
		if h.recvOrigDest && noob > 0 {
			payload.OriginalDestination = RetrieveOriginalDest(oobBytes[:noob])
			if payload.OriginalDestination.IsValid() {
				newError("UDP original destination: ", payload.OriginalDestination).AtDebug().WriteToLog()
			} else {
				newError("failed to read UDP original destination").WriteToLog()
			}
		}

		select {
		case c <- payload:
		default:
		}

	}
}

// Addr implements net.Listener.
func (h *Hub) Addr() net.Addr {
	return h.conn.LocalAddr()
}

func (h *Hub) Receive() <-chan *Payload {
	return h.cache
}
<commit_msg>release buffer<commit_after>package udp

import (
	"v2ray.com/core/common/buf"
	"v2ray.com/core/common/net"
)

// Payload represents a single UDP payload.
type Payload struct {
	Content             *buf.Buffer
	Source              net.Destination
	OriginalDestination net.Destination
}

type HubOption func(h *Hub)

func HubCapacity(cap int) HubOption {
	return func(h *Hub) {
		h.capacity = cap
	}
}

func HubReceiveOriginalDestination(r bool) HubOption {
	return func(h *Hub) {
		h.recvOrigDest = r
	}
}

type Hub struct {
	conn         *net.UDPConn
	cache        chan *Payload
	capacity     int
	recvOrigDest bool
}

func ListenUDP(address net.Address, port net.Port, options ...HubOption) (*Hub, error) {
	udpConn, err := net.ListenUDP("udp", &net.UDPAddr{
		IP:   address.IP(),
		Port: int(port),
	})
	if err != nil {
		return nil, err
	}
	newError("listening UDP on ", address, ":", port).WriteToLog()
	hub := &Hub{
		conn:         udpConn,
		capacity:     256,
		recvOrigDest: false,
	}
	for _, opt := range options {
		opt(hub)
	}

	hub.cache = make(chan *Payload, hub.capacity)

	if hub.recvOrigDest {
		rawConn, err := udpConn.SyscallConn()
		if err != nil {
			return nil, newError("failed to get fd").Base(err)
		}
		err = rawConn.Control(func(fd uintptr) {
			if err := SetOriginalDestOptions(int(fd)); err != nil {
				newError("failed to set socket options").Base(err).WriteToLog()
			}
		})
		if err != nil {
			return nil, newError("failed to control socket").Base(err)
		}
	}

	go hub.start()
	return hub, nil
}

// Close implements net.Listener.
func (h *Hub) Close() error {
	h.conn.Close()
	return nil
}

func (h *Hub) WriteTo(payload []byte, dest net.Destination) (int, error) {
	return h.conn.WriteToUDP(payload, &net.UDPAddr{
		IP:   dest.Address.IP(),
		Port: int(dest.Port),
	})
}

func (h *Hub) start() {
	c := h.cache
	defer close(c)

	oobBytes := make([]byte, 256)

	for {
		buffer := buf.New()
		var noob int
		var addr *net.UDPAddr
		err := buffer.Reset(func(b []byte) (int, error) {
			n, nb, _, a, e := ReadUDPMsg(h.conn, b, oobBytes)
			noob = nb
			addr = a
			return n, e
		})

		if err != nil {
			newError("failed to read UDP msg").Base(err).WriteToLog()
			buffer.Release()
			break
		}

		if buffer.IsEmpty() {
			buffer.Release()
			continue
		}

		payload := &Payload{
			Content: buffer,
			Source:  net.UDPDestination(net.IPAddress(addr.IP), net.Port(addr.Port)),
		}
		if h.recvOrigDest && noob > 0 {
			payload.OriginalDestination = RetrieveOriginalDest(oobBytes[:noob])
			if payload.OriginalDestination.IsValid() {
				newError("UDP original destination: ", payload.OriginalDestination).AtDebug().WriteToLog()
			} else {
				newError("failed to read UDP original destination").WriteToLog()
			}
		}

		select {
		case c <- payload:
		default:
			buffer.Release()
			payload.Content = nil
		}

	}
}

// Addr implements net.Listener.
func (h *Hub) Addr() net.Addr {
	return h.conn.LocalAddr()
}

func (h *Hub) Receive() <-chan *Payload {
	return h.cache
}
<|endoftext|>


<commit_before>package blackjack

import (
	"github.com/jkomoros/boardgame"
	"github.com/jkomoros/boardgame/playingcards"
	"github.com/jkomoros/boardgame/storage/memory"
	"testing"
)

func TestHandValue(t *testing.T) {

	manager := NewManager(memory.NewStorageManager())

	chest := manager.Chest()

	deck := chest.Deck("cards")

	tests := []struct {
		state    *playerState
		expected int
	}{
		{
			&playerState{
				Hand: createHand(deck, playingcards.Rank2, playingcards.Rank3, playingcards.Rank4),
			},
			9,
		},
		{
			&playerState{
				Hand: createHand(deck, playingcards.RankAce),
			},
			11,
		},
		{
			&playerState{
				Hand: createHand(deck, playingcards.RankAce, playingcards.RankAce),
			},
			12,
		},
		{
			&playerState{
				Hand: createHand(deck, playingcards.RankJack, playingcards.RankKing, playingcards.RankAce),
			},
			21,
		},
	}

	for i, test := range tests {
		result := test.state.HandValue()

		if result != test.expected {
			t.Error("Test", i, "Failed. Got", result, "wanted", test.expected)
		}
	}
}

func createHand(deck *boardgame.Deck, ranks ...playingcards.Rank) *boardgame.GrowableStack {
	result := boardgame.NewGrowableStack(deck, 0)

	givenCards := make(map[int]bool)

	for i, rank := range ranks {
		for i, c := range deck.Components() {

			//Skip cards we have already used
			if givenCards[i] {
				continue
			}

			card := c.Values.(*playingcards.Card)

			if card.Rank == rank {
				//Found one!
				result.InsertBack(c)
				givenCards[i] = true
				break
			}
		}
		if result.Len() <= i {
			//Didn't find a card, must not be any left!
			panic("Wasn't possible to fulfill the cards you asked for")
		}
	}

	return result

}
<commit_msg>Fixed failing test in last commit.<commit_after>package blackjack

import (
	"github.com/jkomoros/boardgame"
	"github.com/jkomoros/boardgame/playingcards"
	"github.com/jkomoros/boardgame/storage/memory"
	"testing"
)

func TestHandValue(t *testing.T) {

	manager := NewManager(memory.NewStorageManager())

	chest := manager.Chest()

	deck := chest.Deck("cards")

	tests := []struct {
		state    *playerState
		expected int
	}{
		{
			&playerState{
				VisibleHand: createHand(deck, playingcards.Rank2, playingcards.Rank3, playingcards.Rank4),
				HiddenHand:  boardgame.NewGrowableStack(deck, 0),
			},
			9,
		},
		{
			&playerState{
				VisibleHand: createHand(deck, playingcards.RankAce),
				HiddenHand:  boardgame.NewGrowableStack(deck, 0),
			},
			11,
		},
		{
			&playerState{
				VisibleHand: createHand(deck, playingcards.RankAce, playingcards.RankAce),
				HiddenHand:  boardgame.NewGrowableStack(deck, 0),
			},
			12,
		},
		{
			&playerState{
				VisibleHand: createHand(deck, playingcards.RankJack, playingcards.RankKing, playingcards.RankAce),
				HiddenHand:  boardgame.NewGrowableStack(deck, 0),
			},
			21,
		},
	}

	for i, test := range tests {
		result := test.state.HandValue()

		if result != test.expected {
			t.Error("Test", i, "Failed. Got", result, "wanted", test.expected)
		}
	}
}

func createHand(deck *boardgame.Deck, ranks ...playingcards.Rank) *boardgame.GrowableStack {
	result := boardgame.NewGrowableStack(deck, 0)

	givenCards := make(map[int]bool)

	for i, rank := range ranks {
		for i, c := range deck.Components() {

			//Skip cards we have already used
			if givenCards[i] {
				continue
			}

			card := c.Values.(*playingcards.Card)

			if card.Rank == rank {
				//Found one!
				result.InsertBack(c)
				givenCards[i] = true
				break
			}
		}
		if result.Len() <= i {
			//Didn't find a card, must not be any left!
			panic("Wasn't possible to fulfill the cards you asked for")
		}
	}

	return result

}
<|endoftext|>


<commit_before>package main

import (
	"crypto/md5"
	"crypto/rand"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"code.google.com/p/go.crypto/ssh"
	"github.com/coreos/shortbread/api"
	"github.com/coreos/shortbread/gitutil"
	"github.com/coreos/shortbread/util"
)

const (
	SHORTBREAD_PRVT_KEY = "SHORTBREAD_PRVT_KEY"
	FingerprintLength   = 16
)

type CertificatesAndMetaData struct {
	cert       *ssh.Certificate
	privateKey string
}
type Fingerprint [16]byte
type CertificateCollection map[Fingerprint][]*CertificatesAndMetaData

var Certificates CertificateCollection
var url string = "git@github.com:joshi4/shortbread-test.git"
var path string = filepath.Join(os.Getenv("HOME"), ".ssh","shortbread/shortbread-test/git")
var mutex = &sync.Mutex{}

func init() {
	Certificates = make(CertificateCollection)
	Certificates.initialize()
}

// Initalize the map based on existing contents of the local git repo, if one exists.
func (c CertificateCollection) initialize() {
	repo, err := gitutil.OpenRepository(url, path)
	if err != nil {
		return
	}
	defer repo.Free()

	index, err := repo.Index()
	if err != nil {
		return
	}
	defer index.Free()

	entryCount := index.EntryCount()
	var i uint
	for i = 0; i < entryCount; i++ {
		indexEntry, err := index.EntryByIndex(i)
		if err != nil {
			continue
		}
		//add to the map only if path ends with `.pub` and after splitting on pathSeparator, length is 2.
		certPath := indexEntry.Path
		certPathSlice := strings.Split(certPath, string(os.PathSeparator))
		dirName := certPathSlice[0]
		if strings.HasSuffix(certPath, "-cert.pub") && len(certPathSlice) == 2 && len(dirName) == 32 {
			certName := certPathSlice[1]
			var fingerprint Fingerprint
			hexadecimal := fingerprint[:]
			hexadecimal, err := hex.DecodeString(dirName)
			if err != nil {
				continue
			}
			copy(fingerprint[:], hexadecimal)
			rawCert, err := ioutil.ReadFile(filepath.Join(repo.Workdir(), certPath))
			if err != nil {
				continue
			}

			cert, err := util.ParseSSHCert(rawCert)
			if err != nil {
				continue
			}

			certs, ok := c[fingerprint]
			certAndKey := &CertificatesAndMetaData{
				cert:       cert,
				privateKey: strings.Split(certName, "-cert.pub")[0],
			}
			if !ok {
				c[fingerprint] = []*CertificatesAndMetaData{certAndKey}
			} else {
				c[fingerprint] = append(certs, certAndKey)
			}

		}
	}
}

// New creates a new certificate based on the information supplied by the user and adds it to the global map.
// Each new entry is logged in a git repo.
func (c CertificateCollection) New(params api.CertificateInfo) error {
	mutex.Lock()
	defer mutex.Unlock()

	repo, err := gitutil.OpenRepository(url, path)
	if err != nil {
		log.Print(err)
		return err
	}
	defer repo.Free()

	privateKeyBytes, err := ioutil.ReadFile(filepath.Join(util.GetenvWithDefault(SHORTBREAD_PRVT_KEY, os.ExpandEnv("$HOME/.ssh")), params.PrivateKey))
	if err != nil {
		return err
	}

	//the private key used to sign the certificate.
	authority, err := ssh.ParsePrivateKey(privateKeyBytes)
	if err != nil {
		return err
	}

	keyToSignBytes := []byte(params.Key)
	keyToSign, _, _, _, err := ssh.ParseAuthorizedKey(keyToSignBytes)
	if err != nil {
		return err
	}

	if keyToSign == nil {
		return errors.New("public key is nil")
	}

	cert := &ssh.Certificate{
		Nonce:       []byte{},
		Key:         keyToSign,
		CertType:    ssh.UserCert,
		KeyId:       "user_" + params.User,
		ValidBefore: params.ValidBefore,
		ValidAfter:  params.ValidAfter,
		Permissions: ssh.Permissions{
			CriticalOptions: map[string]string{},
			Extensions:      map[string]string{},
		},
		ValidPrincipals: []string{params.User},
	}

	for _, perm := range params.Permission.Extensions {
		cert.Permissions.Extensions[perm] = ""
	}

	for _, criticalOpts := range params.Permission.CriticalOptions {
		cert.Permissions.CriticalOptions[criticalOpts] = ""
	}

	err = cert.SignCert(rand.Reader, authority)
	if err != nil {
		return err
	}

	certAndKey := &CertificatesAndMetaData{
		cert:       cert,
		privateKey: params.PrivateKey,
	}

	fingerprint, err := getFingerPrint(params.Key)
	if err != nil {
		return err
	}

	certs, ok := c[fingerprint]
	if !ok {
		c[fingerprint] = []*CertificatesAndMetaData{certAndKey}
	} else {
		c[fingerprint] = append(certs, certAndKey)
	}
	certDirPath := filepath.Join(repo.Workdir(), fmt.Sprintf("%x", fingerprint))
	fileInfo, err := os.Stat(certDirPath)
	if err != nil || !fileInfo.IsDir() {
		err := os.Mkdir(certDirPath, os.ModePerm)
		if err != nil {
			return err
		}
	}

	certPath := filepath.Join(certDirPath, (params.PrivateKey + "-cert.pub"))
	err = ioutil.WriteFile(certPath, ssh.MarshalAuthorizedKey(cert), 0600)
	if err != nil {
		return err
	}

	relativeCertPath := filepath.Join(fmt.Sprintf("%x", fingerprint), (params.PrivateKey + "-cert.pub"))

	err = gitutil.AddAndCommit(repo, []string{relativeCertPath}, fmt.Sprintf("added cert for user: %s with private key name: %s", params.User, params.PrivateKey))
	if err != nil {
		return err
	}

	err = gitutil.Push(repo)
	if err != nil {
		return err
	}

	return nil
}

// Revoke uses the public key provided in the request to delete the corresponding certificate
// from the map. If an username is provided then a certificate is deleted only if it's listed as a valid principal
func (c CertificateCollection) Revoke(revokeInfo api.RevokeCertificate) error {
	fingerprint, err := getFingerPrint(revokeInfo.Key)
	if err != nil {
		return err
	}

	certs, ok := c[fingerprint]
	if !ok {
		return errors.New("certificate not found, check if you have specified the correct public key")
	}

	user := revokeInfo.User
	checkPrincipal := func(certs []*CertificatesAndMetaData, principal string) bool {
		for _, certData := range certs {
			if certData.cert.ValidPrincipals[0] == principal {
				return true
			}
		}
		return false
	}
	if user != "" && checkPrincipal(certs, user) {
		return errors.New("certificate's valid principal differs from username provided")
	}

	delete(c, fingerprint)
	return nil
}

// SignHandler creates a new certificate from the parameters specified in the request.
func SignHandler(w http.ResponseWriter, r *http.Request) {
	decoder := json.NewDecoder(r.Body)
	var params api.CertificateInfo

	err := decoder.Decode(&params)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "%s", err.Error())
		return
	}

	err = Certificates.New(params)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "%s", err.Error())
	}
}

func RevokeHandler(w http.ResponseWriter, r *http.Request) {
	decoder := json.NewDecoder(r.Body)
	var revokeInfo api.RevokeCertificate

	err := decoder.Decode(&revokeInfo)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "%s", err.Error())
		return
	}

	err = Certificates.Revoke(revokeInfo)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "%s", err.Error())
	}
}

func ClientHandler(w http.ResponseWriter, r *http.Request) {
	fingerprint, _ := getFingerPrint(strings.SplitN(r.URL.Path, "/", 4)[3])
	certs, ok := Certificates[fingerprint]
	if !ok {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "%s", "key does not exist.")
		return
	}

	certsWithKey := new(api.CertificatesWithKey)
	for _, certAndKey := range certs {
		transferData := &api.CertificateAndPrivateKey{
			Cert:       string(ssh.MarshalAuthorizedKey(certAndKey.cert)),
			PrivateKey: certAndKey.privateKey,
		}
		certsWithKey.List = append(certsWithKey.List, transferData)
	}
	enc := json.NewEncoder(w)
	enc.Encode(certsWithKey)

}

// Fingerprint for a public key is the md5 sum of the base64 encoded key.
func getFingerPrint(publicKey string) (fp Fingerprint, err error) {
	data, err := base64.StdEncoding.DecodeString(strings.Split(publicKey, " ")[1])
	if err != nil {
		return fp, err
	}
	fp = md5.Sum(data)
	return fp, nil
}

func main() {
	http.HandleFunc("/v1/sign", SignHandler)
	http.HandleFunc("/v1/revoke", RevokeHandler)
	http.HandleFunc("/v1/getcerts/", ClientHandler)
	http.ListenAndServe(":8080", nil)
}
<commit_msg>commented out code to git push<commit_after>package main

import (
	"crypto/md5"
	"crypto/rand"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"sync"

	"code.google.com/p/go.crypto/ssh"
	"github.com/coreos/shortbread/api"
	"github.com/coreos/shortbread/gitutil"
	"github.com/coreos/shortbread/util"
)

const (
	SHORTBREAD_PRVT_KEY = "SHORTBREAD_PRVT_KEY"
	FingerprintLength   = 16
)

type CertificatesAndMetaData struct {
	cert       *ssh.Certificate
	privateKey string
}
type Fingerprint [16]byte
type CertificateCollection map[Fingerprint][]*CertificatesAndMetaData

var Certificates CertificateCollection
var url string = "git@github.com:joshi4/shortbread-test.git"
var path string = filepath.Join(os.Getenv("HOME"), ".ssh","shortbread/shortbread-test/git")
var mutex = &sync.Mutex{}

func init() {
	Certificates = make(CertificateCollection)
	Certificates.initialize()
}

// Initalize the map based on existing contents of the local git repo, if one exists.
func (c CertificateCollection) initialize() {
	repo, err := gitutil.OpenRepository(url, path)
	if err != nil {
		return
	}
	defer repo.Free()

	index, err := repo.Index()
	if err != nil {
		return
	}
	defer index.Free()

	entryCount := index.EntryCount()
	var i uint
	for i = 0; i < entryCount; i++ {
		indexEntry, err := index.EntryByIndex(i)
		if err != nil {
			continue
		}
		//add to the map only if path ends with `.pub` and after splitting on pathSeparator, length is 2.
		certPath := indexEntry.Path
		certPathSlice := strings.Split(certPath, string(os.PathSeparator))
		dirName := certPathSlice[0]
		if strings.HasSuffix(certPath, "-cert.pub") && len(certPathSlice) == 2 && len(dirName) == 32 {
			certName := certPathSlice[1]
			var fingerprint Fingerprint
			hexadecimal := fingerprint[:]
			hexadecimal, err := hex.DecodeString(dirName)
			if err != nil {
				continue
			}
			copy(fingerprint[:], hexadecimal)
			rawCert, err := ioutil.ReadFile(filepath.Join(repo.Workdir(), certPath))
			if err != nil {
				continue
			}

			cert, err := util.ParseSSHCert(rawCert)
			if err != nil {
				continue
			}

			certs, ok := c[fingerprint]
			certAndKey := &CertificatesAndMetaData{
				cert:       cert,
				privateKey: strings.Split(certName, "-cert.pub")[0],
			}
			if !ok {
				c[fingerprint] = []*CertificatesAndMetaData{certAndKey}
			} else {
				c[fingerprint] = append(certs, certAndKey)
			}

		}
	}
}

// New creates a new certificate based on the information supplied by the user and adds it to the global map.
// Each new entry is logged in a git repo.
func (c CertificateCollection) New(params api.CertificateInfo) error {
	mutex.Lock()
	defer mutex.Unlock()

	repo, err := gitutil.OpenRepository(url, path)
	if err != nil {
		log.Print(err)
		return err
	}
	defer repo.Free()

	privateKeyBytes, err := ioutil.ReadFile(filepath.Join(util.GetenvWithDefault(SHORTBREAD_PRVT_KEY, os.ExpandEnv("$HOME/.ssh")), params.PrivateKey))
	if err != nil {
		return err
	}

	//the private key used to sign the certificate.
	authority, err := ssh.ParsePrivateKey(privateKeyBytes)
	if err != nil {
		return err
	}

	keyToSignBytes := []byte(params.Key)
	keyToSign, _, _, _, err := ssh.ParseAuthorizedKey(keyToSignBytes)
	if err != nil {
		return err
	}

	if keyToSign == nil {
		return errors.New("public key is nil")
	}

	cert := &ssh.Certificate{
		Nonce:       []byte{},
		Key:         keyToSign,
		CertType:    ssh.UserCert,
		KeyId:       "user_" + params.User,
		ValidBefore: params.ValidBefore,
		ValidAfter:  params.ValidAfter,
		Permissions: ssh.Permissions{
			CriticalOptions: map[string]string{},
			Extensions:      map[string]string{},
		},
		ValidPrincipals: []string{params.User},
	}

	for _, perm := range params.Permission.Extensions {
		cert.Permissions.Extensions[perm] = ""
	}

	for _, criticalOpts := range params.Permission.CriticalOptions {
		cert.Permissions.CriticalOptions[criticalOpts] = ""
	}

	err = cert.SignCert(rand.Reader, authority)
	if err != nil {
		return err
	}

	certAndKey := &CertificatesAndMetaData{
		cert:       cert,
		privateKey: params.PrivateKey,
	}

	fingerprint, err := getFingerPrint(params.Key)
	if err != nil {
		return err
	}

	certs, ok := c[fingerprint]
	if !ok {
		c[fingerprint] = []*CertificatesAndMetaData{certAndKey}
	} else {
		c[fingerprint] = append(certs, certAndKey)
	}
	certDirPath := filepath.Join(repo.Workdir(), fmt.Sprintf("%x", fingerprint))
	fileInfo, err := os.Stat(certDirPath)
	if err != nil || !fileInfo.IsDir() {
		err := os.Mkdir(certDirPath, os.ModePerm)
		if err != nil {
			return err
		}
	}

	certPath := filepath.Join(certDirPath, (params.PrivateKey + "-cert.pub"))
	err = ioutil.WriteFile(certPath, ssh.MarshalAuthorizedKey(cert), 0600)
	if err != nil {
		return err
	}

	relativeCertPath := filepath.Join(fmt.Sprintf("%x", fingerprint), (params.PrivateKey + "-cert.pub"))

	err = gitutil.AddAndCommit(repo, []string{relativeCertPath}, fmt.Sprintf("added cert for user: %s with private key name: %s", params.User, params.PrivateKey))
	if err != nil {
		return err
	}

	// err = gitutil.Push(repo)
	// if err != nil {
	// 	return err
	// }

	return nil
}

// Revoke uses the public key provided in the request to delete the corresponding certificate
// from the map. If an username is provided then a certificate is deleted only if it's listed as a valid principal
func (c CertificateCollection) Revoke(revokeInfo api.RevokeCertificate) error {
	fingerprint, err := getFingerPrint(revokeInfo.Key)
	if err != nil {
		return err
	}

	certs, ok := c[fingerprint]
	if !ok {
		return errors.New("certificate not found, check if you have specified the correct public key")
	}

	user := revokeInfo.User
	checkPrincipal := func(certs []*CertificatesAndMetaData, principal string) bool {
		for _, certData := range certs {
			if certData.cert.ValidPrincipals[0] == principal {
				return true
			}
		}
		return false
	}
	if user != "" && checkPrincipal(certs, user) {
		return errors.New("certificate's valid principal differs from username provided")
	}

	delete(c, fingerprint)
	return nil
}

// SignHandler creates a new certificate from the parameters specified in the request.
func SignHandler(w http.ResponseWriter, r *http.Request) {
	decoder := json.NewDecoder(r.Body)
	var params api.CertificateInfo

	err := decoder.Decode(&params)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "%s", err.Error())
		return
	}

	err = Certificates.New(params)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "%s", err.Error())
	}
}

func RevokeHandler(w http.ResponseWriter, r *http.Request) {
	decoder := json.NewDecoder(r.Body)
	var revokeInfo api.RevokeCertificate

	err := decoder.Decode(&revokeInfo)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "%s", err.Error())
		return
	}

	err = Certificates.Revoke(revokeInfo)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "%s", err.Error())
	}
}

func ClientHandler(w http.ResponseWriter, r *http.Request) {
	fingerprint, _ := getFingerPrint(strings.SplitN(r.URL.Path, "/", 4)[3])
	certs, ok := Certificates[fingerprint]
	if !ok {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "%s", "key does not exist.")
		return
	}

	certsWithKey := new(api.CertificatesWithKey)
	for _, certAndKey := range certs {
		transferData := &api.CertificateAndPrivateKey{
			Cert:       string(ssh.MarshalAuthorizedKey(certAndKey.cert)),
			PrivateKey: certAndKey.privateKey,
		}
		certsWithKey.List = append(certsWithKey.List, transferData)
	}
	enc := json.NewEncoder(w)
	enc.Encode(certsWithKey)

}

// Fingerprint for a public key is the md5 sum of the base64 encoded key.
func getFingerPrint(publicKey string) (fp Fingerprint, err error) {
	data, err := base64.StdEncoding.DecodeString(strings.Split(publicKey, " ")[1])
	if err != nil {
		return fp, err
	}
	fp = md5.Sum(data)
	return fp, nil
}

func main() {
	http.HandleFunc("/v1/sign", SignHandler)
	http.HandleFunc("/v1/revoke", RevokeHandler)
	http.HandleFunc("/v1/getcerts/", ClientHandler)
	http.ListenAndServe(":8080", nil)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
	"strings"
	"sync"

	"github.com/dgrijalva/jwt-go"
)

// Todo is a representation of each item that
// we are going to maintain in our service
type Todo struct {
	ID        uint64
	Task      string
	Completed bool
}

var todos []Todo
var lock sync.RWMutex

var hmacSampleSecret = []byte("Top secret signing key")

// A middleware for validating JWT tokens
func authCheck(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		tokenString := r.Header.Get("Authorization")
		if tokenString == "" {
			http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
			return
		}

		tokenString = strings.TrimPrefix(tokenString, "Bearer ")
		token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
			// Don't forget to validate the alg is what you expect:
			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
				return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
			}
			return hmacSampleSecret, nil
		})

		if err != nil {
			http.Error(w, err.Error(), http.StatusUnauthorized)
			return
		}

		if claims, ok := token.Claims.(jwt.StandardClaims); ok && token.Valid {
			log.Println(claims)
		} else {
			http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func main() {
	http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
		// Authenticate and return JWT
	})

	http.Handle("/todos", authCheck(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodGet {
			// Return all the Todo items
		} else if r.Method == http.MethodPost {
			// Create a new Todo item
		} else {
			http.NotFound(w, r)
		}
	})))

	http.Handle("/todo", authCheck(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodPut {
			// Update the particular Todo item
		} else if r.Method == http.MethodDelete {
			// Delete the particular Todo item
		} else {
			http.NotFound(w, r)
		}
	})))

	log.Fatal(http.ListenAndServe(":8080", nil))
}
<commit_msg>GET all todos<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"
	"sync"

	"github.com/dgrijalva/jwt-go"
)

// Todo is a representation of each item that
// we are going to maintain in our service
type Todo struct {
	ID        uint64
	Task      string
	Completed bool
}

var todos []Todo
var lock sync.RWMutex

var hmacSampleSecret = []byte("Top secret signing key")

// A middleware for validating JWT tokens
func authCheck(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		tokenString := r.Header.Get("Authorization")
		if tokenString == "" {
			http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
			return
		}

		tokenString = strings.TrimPrefix(tokenString, "Bearer ")
		token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
			// Don't forget to validate the alg is what you expect:
			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
				return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
			}
			return hmacSampleSecret, nil
		})

		if err != nil {
			http.Error(w, err.Error(), http.StatusUnauthorized)
			return
		}

		if claims, ok := token.Claims.(jwt.StandardClaims); ok && token.Valid {
			log.Println(claims)
		} else {
			http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func main() {
	http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
		// Authenticate and return JWT
	})

	http.Handle("/todos", authCheck(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodGet {
			// Return all the Todo items
			lock.RLock()
			defer lock.RUnlock()

			j, err := json.Marshal(todos)
			if err != nil {
				log.Println(err)
				http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
				return
			}
			w.Header().Set("Content-Type", "application/json")
			w.Write(j)

		} else if r.Method == http.MethodPost {
			// Create a new Todo item
		} else {
			http.NotFound(w, r)
		}
	})))

	http.Handle("/todo", authCheck(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodPut {
			// Update the particular Todo item
		} else if r.Method == http.MethodDelete {
			// Delete the particular Todo item
		} else {
			http.NotFound(w, r)
		}
	})))

	log.Fatal(http.ListenAndServe(":8080", nil))
}
<|endoftext|>


<commit_before>package main

import "container/list"
import "encoding/json"
import "expvar"
import "flag"
import "log"
import "net/http"
import "strconv"
import "time"

var port = flag.Int("port", 21059, "Port to listen on")

var speak_count = expvar.NewInt("speak_count")
var fetch_count = expvar.NewInt("fetch_count")
var fetch_wait_count = expvar.NewInt("fetch_wait_count")
var fetch_wake_count = expvar.NewInt("fetch_wake_count")

type Message struct {
	Time time.Time
	ID   string
	Text string
}

type StoreRequest struct {
	StartTime time.Time
	Messages  chan<- []Message
}

type Store struct {
	Add chan *Message
	Get chan *StoreRequest
}

// TODO: Monotonic clock

func manage_store(store Store) {
	messages := list.New()
	message_count := 0
	max_messages := 1000
	waiting := list.New()
main:
	for {
		select {
		case new_message, ok := <-store.Add:
			if !ok {
				break main
			}
			speak_count.Add(1)
			for waiter := waiting.Front(); waiter != nil; waiter = waiter.Next() {
				waiter.Value.(*StoreRequest).Messages <- []Message{*new_message}
				close(waiter.Value.(*StoreRequest).Messages)
				fetch_wake_count.Add(1)
			}
			waiting.Init()
			messages.PushBack(new_message)
			if message_count < max_messages {
				message_count++
			} else {
				messages.Remove(messages.Front())
			}
		case request, ok := <-store.Get:
			if !ok {
				break main
			}
			fetch_count.Add(1)
			if messages.Back() == nil || !request.StartTime.Before(messages.Back().Value.(*Message).Time) {
				waiting.PushBack(request)
				fetch_wait_count.Add(1)
			} else {
				start := messages.Back()
				response_size := 1
				if messages.Front().Value.(*Message).Time.After(request.StartTime) {
					start = messages.Front()
					response_size = message_count
				} else {
					for start.Prev().Value.(*Message).Time.After(request.StartTime) {
						start = start.Prev()
						response_size++
					}
				}
				response_messages := make([]Message, 0, response_size)
				for m := start; m != nil; m = m.Next() {
					response_messages = append(response_messages, *m.Value.(*Message))
				}
				request.Messages <- response_messages
			}
		}
	}
}

func start_store() Store {
	store := Store{make(chan *Message, 20), make(chan *StoreRequest, 20)}
	go manage_store(store)
	return store
}

const frame_html = `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <script type="text/javascript"><!--//--><![CDATA[//><!--
  var since;
  function go() {
   var delay = 10000;
   var xhr = new XMLHttpRequest();
   xhr.onreadystatechange = function() {
    if (this.readyState == this.DONE) {
     if (this.status == 200) {
      var rtxt = this.responseText;
      if (rtxt != null) {
       var r = JSON.parse(rtxt);
       if (r != null) {
        window.parent.postMessage(rtxt, "*");
        delay = 40;
        if (r.length >= 1 && "Time" in r[r.length-1]) {
         since = r[r.length-1]["Time"];
        }
       }
      }
     }
     window.setTimeout(go, delay);
    }
   }
   var uri = "/fetch";
   if (since) {
    uri += '?since="' + since + '"';
   }
   xhr.open("GET", uri);
   xhr.send();
  }
  //--><!]]></script>
</head>
<body onload="go()">
</body>
</html>
`

func start_server(store Store) {
	http.HandleFunc("/fetch", func(w http.ResponseWriter, r *http.Request) {
		var since time.Time
		url_since := r.FormValue("since")
		if url_since != "" {
			err := json.Unmarshal([]byte(url_since), &since)
			if err != nil {
				log.Print("fetch: parse since: ", err)
				w.WriteHeader(http.StatusBadRequest)
				w.Write([]byte("Could not parse since as date"))
				return
			}
		}
		messages_from_store := make(chan []Message, 1)
		store.Get <- &StoreRequest{since, messages_from_store}

		json_encoded, err := json.Marshal(<-messages_from_store)
		if err != nil {
			log.Print("json encode: ", err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.Header().Add("Content-Type", "application/json")
		w.Write(json_encoded)
	})

	http.HandleFunc("/speak", func(w http.ResponseWriter, r *http.Request) {
		store.Add <- &Message{
			time.Now(),
			r.FormValue("id"),
			r.FormValue("text")}
	})

	http.HandleFunc("/frame", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(frame_html));
	})

	log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*port), nil))
}

func main() {
	flag.Parse()
	store := start_store()
	start_server(store)
}
<commit_msg>Track /frame usage.<commit_after>package main

import "container/list"
import "encoding/json"
import "expvar"
import "flag"
import "log"
import "net/http"
import "strconv"
import "time"

var port = flag.Int("port", 21059, "Port to listen on")

var frame_count = expvar.NewInt("frame_count")
var speak_count = expvar.NewInt("speak_count")
var fetch_count = expvar.NewInt("fetch_count")
var fetch_wait_count = expvar.NewInt("fetch_wait_count")
var fetch_wake_count = expvar.NewInt("fetch_wake_count")

type Message struct {
	Time time.Time
	ID   string
	Text string
}

type StoreRequest struct {
	StartTime time.Time
	Messages  chan<- []Message
}

type Store struct {
	Add chan *Message
	Get chan *StoreRequest
}

// TODO: Monotonic clock

func manage_store(store Store) {
	messages := list.New()
	message_count := 0
	max_messages := 1000
	waiting := list.New()
main:
	for {
		select {
		case new_message, ok := <-store.Add:
			if !ok {
				break main
			}
			speak_count.Add(1)
			for waiter := waiting.Front(); waiter != nil; waiter = waiter.Next() {
				waiter.Value.(*StoreRequest).Messages <- []Message{*new_message}
				close(waiter.Value.(*StoreRequest).Messages)
				fetch_wake_count.Add(1)
			}
			waiting.Init()
			messages.PushBack(new_message)
			if message_count < max_messages {
				message_count++
			} else {
				messages.Remove(messages.Front())
			}
		case request, ok := <-store.Get:
			if !ok {
				break main
			}
			fetch_count.Add(1)
			if messages.Back() == nil || !request.StartTime.Before(messages.Back().Value.(*Message).Time) {
				waiting.PushBack(request)
				fetch_wait_count.Add(1)
			} else {
				start := messages.Back()
				response_size := 1
				if messages.Front().Value.(*Message).Time.After(request.StartTime) {
					start = messages.Front()
					response_size = message_count
				} else {
					for start.Prev().Value.(*Message).Time.After(request.StartTime) {
						start = start.Prev()
						response_size++
					}
				}
				response_messages := make([]Message, 0, response_size)
				for m := start; m != nil; m = m.Next() {
					response_messages = append(response_messages, *m.Value.(*Message))
				}
				request.Messages <- response_messages
			}
		}
	}
}

func start_store() Store {
	store := Store{make(chan *Message, 20), make(chan *StoreRequest, 20)}
	go manage_store(store)
	return store
}

const frame_html = `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <script type="text/javascript"><!--//--><![CDATA[//><!--
  var since;
  function go() {
   var delay = 10000;
   var xhr = new XMLHttpRequest();
   xhr.onreadystatechange = function() {
    if (this.readyState == this.DONE) {
     if (this.status == 200) {
      var rtxt = this.responseText;
      if (rtxt != null) {
       var r = JSON.parse(rtxt);
       if (r != null) {
        window.parent.postMessage(rtxt, "*");
        delay = 40;
        if (r.length >= 1 && "Time" in r[r.length-1]) {
         since = r[r.length-1]["Time"];
        }
       }
      }
     }
     window.setTimeout(go, delay);
    }
   }
   var uri = "/fetch";
   if (since) {
    uri += '?since="' + since + '"';
   }
   xhr.open("GET", uri);
   xhr.send();
  }
  //--><!]]></script>
</head>
<body onload="go()">
</body>
</html>
`

func start_server(store Store) {
	http.HandleFunc("/fetch", func(w http.ResponseWriter, r *http.Request) {
		var since time.Time
		url_since := r.FormValue("since")
		if url_since != "" {
			err := json.Unmarshal([]byte(url_since), &since)
			if err != nil {
				log.Print("fetch: parse since: ", err)
				w.WriteHeader(http.StatusBadRequest)
				w.Write([]byte("Could not parse since as date"))
				return
			}
		}
		messages_from_store := make(chan []Message, 1)
		store.Get <- &StoreRequest{since, messages_from_store}

		json_encoded, err := json.Marshal(<-messages_from_store)
		if err != nil {
			log.Print("json encode: ", err)
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		w.Header().Add("Content-Type", "application/json")
		w.Write(json_encoded)
	})

	http.HandleFunc("/speak", func(w http.ResponseWriter, r *http.Request) {
		store.Add <- &Message{
			time.Now(),
			r.FormValue("id"),
			r.FormValue("text")}
	})

	http.HandleFunc("/frame", func(w http.ResponseWriter, r *http.Request) {
		frame_count.Add(1)
		w.Write([]byte(frame_html));
	})

	log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*port), nil))
}

func main() {
	flag.Parse()
	store := start_store()
	start_server(store)
}
<|endoftext|>