<commit_before>package commands

import (
	"fmt"
	"os"

	"github.com/cloudfoundry/cli/cf/command_registry"
	testreq "github.com/cloudfoundry/cli/testhelpers/requirements"
	testterm "github.com/cloudfoundry/cli/testhelpers/terminal"
	"github.com/simonleung8/flags"
)

type RunCommandResult int

const (
	RunCommandResultSuccess            = iota
	RunCommandResultFailed             = iota
	RunCommandResultRequirementsFailed = iota
)

func RunCliCommand(cmdName string, args []string, requirementsFactory *testreq.FakeReqFactory, updateFunc func(bool), pluginCall bool) (passedRequirements bool) {
	updateFunc(pluginCall)
	cmd := command_registry.Commands.FindCommand(cmdName)
	context := flags.NewFlagContext(cmd.MetaData().Flags)
	context.SkipFlagParsing(cmd.MetaData().SkipFlagParsing)
	err := context.Parse(args...)
	if err != nil {
		fmt.Println("ERROR:", err)
		os.Exit(1)
	}

	defer func() {
		errMsg := recover()

		if errMsg != nil && errMsg != testterm.QuietPanic {
			panic(errMsg)
		}
	}()
	requirements, err := cmd.Requirements(requirementsFactory, context)
	if err != nil {
		return false
	}

	for _, requirement := range requirements {
		if !requirement.Execute() {
			return false
		}
	}

	passedRequirements = true

	cmd.Execute(context)

	return
}

func RunCliCommandWithoutDependency(cmdName string, args []string, requirementsFactory *testreq.FakeReqFactory) (passedRequirements bool) {
	cmd := command_registry.Commands.FindCommand(cmdName)
	context := flags.NewFlagContext(cmd.MetaData().Flags)
	context.SkipFlagParsing(cmd.MetaData().SkipFlagParsing)
	err := context.Parse(args...)
	if err != nil {
		fmt.Println("ERROR:", err)
		os.Exit(1)
	}

	defer func() {
		errMsg := recover()

		if errMsg != nil && errMsg != testterm.QuietPanic {
			panic(errMsg)
		}
	}()
	requirements, err := cmd.Requirements(requirementsFactory, context)
	if err != nil {
		return false
	}

	for _, requirement := range requirements {
		if !requirement.Execute() {
			return false
		}
	}

	passedRequirements = true

	cmd.Execute(context)

	return
}

func RunCommandMoreBetter(cmdName string, args []string, requirementsFactory *testreq.FakeReqFactory, updateFunc func(bool), pluginCall bool) (result RunCommandResult) {
	updateFunc(pluginCall)
	cmd := command_registry.Commands.FindCommand(cmdName)
	context := flags.NewFlagContext(cmd.MetaData().Flags)
	context.SkipFlagParsing(cmd.MetaData().SkipFlagParsing)
	err := context.Parse(args...)
	if err != nil {
		fmt.Println("ERROR:", err)
		return RunCommandResultFailed
	}

	defer func() {
		errMsg := recover()

		if errMsg != nil && errMsg != testterm.QuietPanic {
			panic(errMsg)
		}

		result = RunCommandResultFailed
	}()
	requirements, err := cmd.Requirements(requirementsFactory, context)
	if err != nil {
		return RunCommandResultRequirementsFailed
	}

	for _, requirement := range requirements {
		if !requirement.Execute() {
			return RunCommandResultRequirementsFailed
		}
	}

	cmd.Execute(context)

	return RunCommandResultSuccess
}
<commit_msg>Remove unused RunCommandMoreBetter helper<commit_after>package commands

import (
	"fmt"
	"os"

	"github.com/cloudfoundry/cli/cf/command_registry"
	testreq "github.com/cloudfoundry/cli/testhelpers/requirements"
	testterm "github.com/cloudfoundry/cli/testhelpers/terminal"
	"github.com/simonleung8/flags"
)

type RunCommandResult int

const (
	RunCommandResultSuccess            = iota
	RunCommandResultFailed             = iota
	RunCommandResultRequirementsFailed = iota
)

func RunCliCommand(cmdName string, args []string, requirementsFactory *testreq.FakeReqFactory, updateFunc func(bool), pluginCall bool) (passedRequirements bool) {
	updateFunc(pluginCall)
	cmd := command_registry.Commands.FindCommand(cmdName)
	context := flags.NewFlagContext(cmd.MetaData().Flags)
	context.SkipFlagParsing(cmd.MetaData().SkipFlagParsing)
	err := context.Parse(args...)
	if err != nil {
		fmt.Println("ERROR:", err)
		os.Exit(1)
	}

	defer func() {
		errMsg := recover()

		if errMsg != nil && errMsg != testterm.QuietPanic {
			panic(errMsg)
		}
	}()
	requirements, err := cmd.Requirements(requirementsFactory, context)
	if err != nil {
		return false
	}

	for _, requirement := range requirements {
		if !requirement.Execute() {
			return false
		}
	}

	passedRequirements = true

	cmd.Execute(context)

	return
}

func RunCliCommandWithoutDependency(cmdName string, args []string, requirementsFactory *testreq.FakeReqFactory) (passedRequirements bool) {
	cmd := command_registry.Commands.FindCommand(cmdName)
	context := flags.NewFlagContext(cmd.MetaData().Flags)
	context.SkipFlagParsing(cmd.MetaData().SkipFlagParsing)
	err := context.Parse(args...)
	if err != nil {
		fmt.Println("ERROR:", err)
		os.Exit(1)
	}

	defer func() {
		errMsg := recover()

		if errMsg != nil && errMsg != testterm.QuietPanic {
			panic(errMsg)
		}
	}()
	requirements, err := cmd.Requirements(requirementsFactory, context)
	if err != nil {
		return false
	}

	for _, requirement := range requirements {
		if !requirement.Execute() {
			return false
		}
	}

	passedRequirements = true

	cmd.Execute(context)

	return
}
<|endoftext|>


<commit_before>// This file contains tests that only compile/work in Go 1.13 and forward
// +build go1.13

package tfexec

import (
	"errors"
	"testing"
)

// test that a suitable error is returned if NewTerraform is called without a valid
// executable path
func TestNoTerraformBinary(t *testing.T) {
	td := testTempDir(t)
	defer os.RemoveAll(td)

	_, err := NewTerraform(td, "")
	if err == nil {
		t.Fatal("expected NewTerraform to error, but it did not")
	}

	var e *ErrNoSuitableBinary
	if !errors.As(err, &e) {
		t.Fatal("expected error to be ErrNoSuitableBinary")
	}
}
<commit_msg>add missing import<commit_after>// This file contains tests that only compile/work in Go 1.13 and forward
// +build go1.13

package tfexec

import (
	"errors"
	"os"
	"testing"
)

// test that a suitable error is returned if NewTerraform is called without a valid
// executable path
func TestNoTerraformBinary(t *testing.T) {
	td := testTempDir(t)
	defer os.RemoveAll(td)

	_, err := NewTerraform(td, "")
	if err == nil {
		t.Fatal("expected NewTerraform to error, but it did not")
	}

	var e *ErrNoSuitableBinary
	if !errors.As(err, &e) {
		t.Fatal("expected error to be ErrNoSuitableBinary")
	}
}
<|endoftext|>


<commit_before>package dockerclient

import (
	"bufio"
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"sync/atomic"
	"time"
)

const (
	APIVersion = "v1.15"
)

var (
	ErrNotFound = errors.New("Not found")

	defaultTimeout = 30 * time.Second
)

type DockerClient struct {
	URL           *url.URL
	HTTPClient    *http.Client
	TLSConfig     *tls.Config
	monitorEvents int32
}

type Error struct {
	StatusCode int
	Status     string
	msg        string
}

func (e Error) Error() string {
	return fmt.Sprintf("%s: %s", e.Status, e.msg)
}

func NewDockerClient(daemonUrl string, tlsConfig *tls.Config) (*DockerClient, error) {
	return NewDockerClientTimeout(daemonUrl, tlsConfig, time.Duration(defaultTimeout))
}

func NewDockerClientTimeout(daemonUrl string, tlsConfig *tls.Config, timeout time.Duration) (*DockerClient, error) {
	u, err := url.Parse(daemonUrl)
	if err != nil {
		return nil, err
	}
	if u.Scheme == "tcp" {
		if tlsConfig == nil {
			u.Scheme = "http"
		} else {
			u.Scheme = "https"
		}
	}
	httpClient := newHTTPClient(u, tlsConfig, timeout)
	return &DockerClient{u, httpClient, tlsConfig, 0}, nil
}

func (client *DockerClient) doRequest(method string, path string, body []byte, headers map[string]string) ([]byte, error) {
	b := bytes.NewBuffer(body)
	req, err := http.NewRequest(method, client.URL.String()+path, b)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	if headers != nil {
		for header, value := range headers {
			req.Header.Add(header, value)
		}
	}
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		if !strings.Contains(err.Error(), "connection refused") && client.TLSConfig == nil {
			return nil, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled daemon without TLS?", err)
		}
		return nil, err
	}
	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode == 404 {
		return nil, ErrNotFound
	}
	if resp.StatusCode >= 400 {
		return nil, Error{StatusCode: resp.StatusCode, Status: resp.Status, msg: string(data)}
	}
	return data, nil
}

func (client *DockerClient) Info() (*Info, error) {
	uri := fmt.Sprintf("/%s/info", APIVersion)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}
	ret := &Info{}
	err = json.Unmarshal(data, &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func (client *DockerClient) ListContainers(all bool, size bool, filters string) ([]Container, error) {
	argAll := 0
	if all == true {
		argAll = 1
	}
	showSize := 0
	if size == true {
		showSize = 1
	}
	uri := fmt.Sprintf("/%s/containers/json?all=%d&size=%d", APIVersion, argAll, showSize)

	if filters != "" {
		uri += "&filters=" + filters
	}

	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}
	ret := []Container{}
	err = json.Unmarshal(data, &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func (client *DockerClient) InspectContainer(id string) (*ContainerInfo, error) {
	uri := fmt.Sprintf("/%s/containers/%s/json", APIVersion, id)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}
	info := &ContainerInfo{}
	err = json.Unmarshal(data, info)
	if err != nil {
		return nil, err
	}
	return info, nil
}

func (client *DockerClient) CreateContainer(config *ContainerConfig, name string) (string, error) {
	data, err := json.Marshal(config)
	if err != nil {
		return "", err
	}
	uri := fmt.Sprintf("/%s/containers/create", APIVersion)
	if name != "" {
		v := url.Values{}
		v.Set("name", name)
		uri = fmt.Sprintf("%s?%s", uri, v.Encode())
	}
	data, err = client.doRequest("POST", uri, data, nil)
	if err != nil {
		return "", err
	}
	result := &RespContainersCreate{}
	err = json.Unmarshal(data, result)
	if err != nil {
		return "", err
	}
	return result.Id, nil
}

func (client *DockerClient) ContainerLogs(id string, options *LogOptions) (io.ReadCloser, error) {
	v := url.Values{}
	v.Add("follow", strconv.FormatBool(options.Follow))
	v.Add("stdout", strconv.FormatBool(options.Stdout))
	v.Add("stderr", strconv.FormatBool(options.Stderr))
	v.Add("timestamps", strconv.FormatBool(options.Timestamps))
	if options.Tail > 0 {
		v.Add("tail", strconv.FormatInt(options.Tail, 10))
	}

	uri := fmt.Sprintf("/%s/containers/%s/logs?%s", APIVersion, id, v.Encode())
	req, err := http.NewRequest("GET", client.URL.String()+uri, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		return nil, err
	}
	return resp.Body, nil
}

func (client *DockerClient) StartContainer(id string, config *HostConfig) error {
	data, err := json.Marshal(config)
	if err != nil {
		return err
	}
	uri := fmt.Sprintf("/%s/containers/%s/start", APIVersion, id)
	_, err = client.doRequest("POST", uri, data, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) StopContainer(id string, timeout int) error {
	uri := fmt.Sprintf("/%s/containers/%s/stop?t=%d", APIVersion, id, timeout)
	_, err := client.doRequest("POST", uri, nil, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) RestartContainer(id string, timeout int) error {
	uri := fmt.Sprintf("/%s/containers/%s/restart?t=%d", APIVersion, id, timeout)
	_, err := client.doRequest("POST", uri, nil, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) KillContainer(id, signal string) error {
	uri := fmt.Sprintf("/%s/containers/%s/kill?signal=%s", APIVersion, id, signal)
	_, err := client.doRequest("POST", uri, nil, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) StartMonitorEvents(cb Callback, args ...interface{}) {
	atomic.StoreInt32(&client.monitorEvents, 1)
	go client.getEvents(cb, args...)
}

func (client *DockerClient) getEvents(cb Callback, args ...interface{}) {
	uri := fmt.Sprintf("%s/%s/events", client.URL.String(), APIVersion)
	resp, err := client.HTTPClient.Get(uri)
	if err != nil {
		log.Printf("GET %s failed: %v", uri, err)
		return
	}
	defer resp.Body.Close()

	dec := json.NewDecoder(resp.Body)
	for atomic.LoadInt32(&client.monitorEvents) > 0 {
		var event *Event
		if err := dec.Decode(&event); err != nil {
			log.Printf("Event decoding failed: %v", err)
			return
		}
		cb(event, args...)
	}
}

func (client *DockerClient) StopAllMonitorEvents() {
	atomic.StoreInt32(&client.monitorEvents, 0)
}

func (client *DockerClient) Version() (*Version, error) {
	uri := fmt.Sprintf("/%s/version", APIVersion)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}
	version := &Version{}
	err = json.Unmarshal(data, version)
	if err != nil {
		return nil, err
	}
	return version, nil
}

func (client *DockerClient) PullImage(name string, auth *AuthConfig) error {
	v := url.Values{}
	v.Set("fromImage", name)
	uri := fmt.Sprintf("/%s/images/create?%s", APIVersion, v.Encode())
	req, err := http.NewRequest("POST", client.URL.String()+uri, nil)
	if auth != nil {
		req.Header.Add("X-Registry-Auth", auth.encode())
	}
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	var finalBytes []byte
	scanner := bufio.NewScanner(resp.Body)
	for scanner.Scan() {
		finalBytes = scanner.Bytes()
	}
	var finalObj map[string]interface{}
	if err = json.Unmarshal(finalBytes, &finalObj); err != nil {
		return err
	}
	if err, ok := finalObj["error"]; ok {
		return fmt.Errorf("%v", err)
	}
	return nil
}

func (client *DockerClient) RemoveContainer(id string, force bool) error {
	argForce := 0
	if force == true {
		argForce = 1
	}
	args := fmt.Sprintf("force=%d", argForce)
	uri := fmt.Sprintf("/%s/containers/%s?%s", APIVersion, id, args)
	_, err := client.doRequest("DELETE", uri, nil, nil)
	return err
}

func (client *DockerClient) ListImages() ([]*Image, error) {
	uri := fmt.Sprintf("/%s/images/json", APIVersion)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}
	var images []*Image
	if err := json.Unmarshal(data, &images); err != nil {
		return nil, err
	}
	return images, nil
}

func (client *DockerClient) RemoveImage(name string) error {
	uri := fmt.Sprintf("/%s/images/%s", APIVersion, name)
	_, err := client.doRequest("DELETE", uri, nil, nil)
	return err
}

func (client *DockerClient) PauseContainer(id string) error {
	uri := fmt.Sprintf("/%s/containers/%s/pause", APIVersion, id)
	_, err := client.doRequest("POST", uri, nil, nil)
	if err != nil {
		return err
	}
	return nil
}
func (client *DockerClient) UnpauseContainer(id string) error {
	uri := fmt.Sprintf("/%s/containers/%s/unpause", APIVersion, id)
	_, err := client.doRequest("POST", uri, nil, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) Exec(config *ExecConfig) (string, error) {
	data, err := json.Marshal(config)
	if err != nil {
		return "", err
	}
	uri := fmt.Sprintf("/containers/%s/exec", config.Container)
	resp, err := client.doRequest("POST", uri, data, nil)
	if err != nil {
		return "", err
	}
	var createExecResp struct {
		Id string
	}
	if err = json.Unmarshal(resp, &createExecResp); err != nil {
		return "", err
	}
	uri = fmt.Sprintf("/exec/%s/start", createExecResp.Id)
	resp, err = client.doRequest("POST", uri, data, nil)
	if err != nil {
		return "", err
	}
	return createExecResp.Id, nil
}
<commit_msg>assume tcp if no scheme<commit_after>package dockerclient

import (
	"bufio"
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"sync/atomic"
	"time"
)

const (
	APIVersion = "v1.15"
)

var (
	ErrNotFound = errors.New("Not found")

	defaultTimeout = 30 * time.Second
)

type DockerClient struct {
	URL           *url.URL
	HTTPClient    *http.Client
	TLSConfig     *tls.Config
	monitorEvents int32
}

type Error struct {
	StatusCode int
	Status     string
	msg        string
}

func (e Error) Error() string {
	return fmt.Sprintf("%s: %s", e.Status, e.msg)
}

func NewDockerClient(daemonUrl string, tlsConfig *tls.Config) (*DockerClient, error) {
	return NewDockerClientTimeout(daemonUrl, tlsConfig, time.Duration(defaultTimeout))
}

func NewDockerClientTimeout(daemonUrl string, tlsConfig *tls.Config, timeout time.Duration) (*DockerClient, error) {
	u, err := url.Parse(daemonUrl)
	if err != nil {
		return nil, err
	}
	if u.Scheme == "" || u.Scheme == "tcp" {
		if tlsConfig == nil {
			u.Scheme = "http"
		} else {
			u.Scheme = "https"
		}
	}
	httpClient := newHTTPClient(u, tlsConfig, timeout)
	return &DockerClient{u, httpClient, tlsConfig, 0}, nil
}

func (client *DockerClient) doRequest(method string, path string, body []byte, headers map[string]string) ([]byte, error) {
	b := bytes.NewBuffer(body)
	req, err := http.NewRequest(method, client.URL.String()+path, b)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	if headers != nil {
		for header, value := range headers {
			req.Header.Add(header, value)
		}
	}
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		if !strings.Contains(err.Error(), "connection refused") && client.TLSConfig == nil {
			return nil, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled daemon without TLS?", err)
		}
		return nil, err
	}
	defer resp.Body.Close()
	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode == 404 {
		return nil, ErrNotFound
	}
	if resp.StatusCode >= 400 {
		return nil, Error{StatusCode: resp.StatusCode, Status: resp.Status, msg: string(data)}
	}
	return data, nil
}

func (client *DockerClient) Info() (*Info, error) {
	uri := fmt.Sprintf("/%s/info", APIVersion)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}
	ret := &Info{}
	err = json.Unmarshal(data, &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func (client *DockerClient) ListContainers(all bool, size bool, filters string) ([]Container, error) {
	argAll := 0
	if all == true {
		argAll = 1
	}
	showSize := 0
	if size == true {
		showSize = 1
	}
	uri := fmt.Sprintf("/%s/containers/json?all=%d&size=%d", APIVersion, argAll, showSize)

	if filters != "" {
		uri += "&filters=" + filters
	}

	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}
	ret := []Container{}
	err = json.Unmarshal(data, &ret)
	if err != nil {
		return nil, err
	}
	return ret, nil
}

func (client *DockerClient) InspectContainer(id string) (*ContainerInfo, error) {
	uri := fmt.Sprintf("/%s/containers/%s/json", APIVersion, id)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}
	info := &ContainerInfo{}
	err = json.Unmarshal(data, info)
	if err != nil {
		return nil, err
	}
	return info, nil
}

func (client *DockerClient) CreateContainer(config *ContainerConfig, name string) (string, error) {
	data, err := json.Marshal(config)
	if err != nil {
		return "", err
	}
	uri := fmt.Sprintf("/%s/containers/create", APIVersion)
	if name != "" {
		v := url.Values{}
		v.Set("name", name)
		uri = fmt.Sprintf("%s?%s", uri, v.Encode())
	}
	data, err = client.doRequest("POST", uri, data, nil)
	if err != nil {
		return "", err
	}
	result := &RespContainersCreate{}
	err = json.Unmarshal(data, result)
	if err != nil {
		return "", err
	}
	return result.Id, nil
}

func (client *DockerClient) ContainerLogs(id string, options *LogOptions) (io.ReadCloser, error) {
	v := url.Values{}
	v.Add("follow", strconv.FormatBool(options.Follow))
	v.Add("stdout", strconv.FormatBool(options.Stdout))
	v.Add("stderr", strconv.FormatBool(options.Stderr))
	v.Add("timestamps", strconv.FormatBool(options.Timestamps))
	if options.Tail > 0 {
		v.Add("tail", strconv.FormatInt(options.Tail, 10))
	}

	uri := fmt.Sprintf("/%s/containers/%s/logs?%s", APIVersion, id, v.Encode())
	req, err := http.NewRequest("GET", client.URL.String()+uri, nil)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-Type", "application/json")
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		return nil, err
	}
	return resp.Body, nil
}

func (client *DockerClient) StartContainer(id string, config *HostConfig) error {
	data, err := json.Marshal(config)
	if err != nil {
		return err
	}
	uri := fmt.Sprintf("/%s/containers/%s/start", APIVersion, id)
	_, err = client.doRequest("POST", uri, data, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) StopContainer(id string, timeout int) error {
	uri := fmt.Sprintf("/%s/containers/%s/stop?t=%d", APIVersion, id, timeout)
	_, err := client.doRequest("POST", uri, nil, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) RestartContainer(id string, timeout int) error {
	uri := fmt.Sprintf("/%s/containers/%s/restart?t=%d", APIVersion, id, timeout)
	_, err := client.doRequest("POST", uri, nil, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) KillContainer(id, signal string) error {
	uri := fmt.Sprintf("/%s/containers/%s/kill?signal=%s", APIVersion, id, signal)
	_, err := client.doRequest("POST", uri, nil, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) StartMonitorEvents(cb Callback, args ...interface{}) {
	atomic.StoreInt32(&client.monitorEvents, 1)
	go client.getEvents(cb, args...)
}

func (client *DockerClient) getEvents(cb Callback, args ...interface{}) {
	uri := fmt.Sprintf("%s/%s/events", client.URL.String(), APIVersion)
	resp, err := client.HTTPClient.Get(uri)
	if err != nil {
		log.Printf("GET %s failed: %v", uri, err)
		return
	}
	defer resp.Body.Close()

	dec := json.NewDecoder(resp.Body)
	for atomic.LoadInt32(&client.monitorEvents) > 0 {
		var event *Event
		if err := dec.Decode(&event); err != nil {
			log.Printf("Event decoding failed: %v", err)
			return
		}
		cb(event, args...)
	}
}

func (client *DockerClient) StopAllMonitorEvents() {
	atomic.StoreInt32(&client.monitorEvents, 0)
}

func (client *DockerClient) Version() (*Version, error) {
	uri := fmt.Sprintf("/%s/version", APIVersion)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}
	version := &Version{}
	err = json.Unmarshal(data, version)
	if err != nil {
		return nil, err
	}
	return version, nil
}

func (client *DockerClient) PullImage(name string, auth *AuthConfig) error {
	v := url.Values{}
	v.Set("fromImage", name)
	uri := fmt.Sprintf("/%s/images/create?%s", APIVersion, v.Encode())
	req, err := http.NewRequest("POST", client.URL.String()+uri, nil)
	if auth != nil {
		req.Header.Add("X-Registry-Auth", auth.encode())
	}
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	var finalBytes []byte
	scanner := bufio.NewScanner(resp.Body)
	for scanner.Scan() {
		finalBytes = scanner.Bytes()
	}
	var finalObj map[string]interface{}
	if err = json.Unmarshal(finalBytes, &finalObj); err != nil {
		return err
	}
	if err, ok := finalObj["error"]; ok {
		return fmt.Errorf("%v", err)
	}
	return nil
}

func (client *DockerClient) RemoveContainer(id string, force bool) error {
	argForce := 0
	if force == true {
		argForce = 1
	}
	args := fmt.Sprintf("force=%d", argForce)
	uri := fmt.Sprintf("/%s/containers/%s?%s", APIVersion, id, args)
	_, err := client.doRequest("DELETE", uri, nil, nil)
	return err
}

func (client *DockerClient) ListImages() ([]*Image, error) {
	uri := fmt.Sprintf("/%s/images/json", APIVersion)
	data, err := client.doRequest("GET", uri, nil, nil)
	if err != nil {
		return nil, err
	}
	var images []*Image
	if err := json.Unmarshal(data, &images); err != nil {
		return nil, err
	}
	return images, nil
}

func (client *DockerClient) RemoveImage(name string) error {
	uri := fmt.Sprintf("/%s/images/%s", APIVersion, name)
	_, err := client.doRequest("DELETE", uri, nil, nil)
	return err
}

func (client *DockerClient) PauseContainer(id string) error {
	uri := fmt.Sprintf("/%s/containers/%s/pause", APIVersion, id)
	_, err := client.doRequest("POST", uri, nil, nil)
	if err != nil {
		return err
	}
	return nil
}
func (client *DockerClient) UnpauseContainer(id string) error {
	uri := fmt.Sprintf("/%s/containers/%s/unpause", APIVersion, id)
	_, err := client.doRequest("POST", uri, nil, nil)
	if err != nil {
		return err
	}
	return nil
}

func (client *DockerClient) Exec(config *ExecConfig) (string, error) {
	data, err := json.Marshal(config)
	if err != nil {
		return "", err
	}
	uri := fmt.Sprintf("/containers/%s/exec", config.Container)
	resp, err := client.doRequest("POST", uri, data, nil)
	if err != nil {
		return "", err
	}
	var createExecResp struct {
		Id string
	}
	if err = json.Unmarshal(resp, &createExecResp); err != nil {
		return "", err
	}
	uri = fmt.Sprintf("/exec/%s/start", createExecResp.Id)
	resp, err = client.doRequest("POST", uri, data, nil)
	if err != nil {
		return "", err
	}
	return createExecResp.Id, nil
}
<|endoftext|>


<commit_before>package dumper

import (
	"database/sql"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"strings"
)

// ExtendedInsertDefaultRowCount: Default rows that will be dumped by each INSERT statement
const (
	ExtendedInsertDefaultRowCount = 100
)

type mySQL struct {
	DB                 *sql.DB
	SelectMap          map[string]map[string]string
	WhereMap           map[string]string
	FilterMap          map[string]string
	UseTableLock       bool
	Log                *log.Logger
	ExtendedInsertRows int
}

// NewMySQLDumper is the constructor
func NewMySQLDumper(db *sql.DB, logger *log.Logger) *mySQL {
	if logger == nil {
		logger = log.New(ioutil.Discard, "", 0)
	}
	return &mySQL{DB: db, Log: logger, ExtendedInsertRows: ExtendedInsertDefaultRowCount}
}

// Lock the table (read only)
func (d *mySQL) LockTableReading(table string) (sql.Result, error) {
	d.Log.Println("Locking table", table, "for reading")
	return d.DB.Exec(fmt.Sprintf("LOCK TABLES `%s` READ", table))
}

// Flush table to ensure that the all active index pages are written to disk
func (d *mySQL) FlushTable(table string) (sql.Result, error) {
	d.Log.Println("Flushing table", table)
	return d.DB.Exec(fmt.Sprintf("FLUSH TABLES `%s`", table))
}

// Release the global read locks
func (d *mySQL) UnlockTables() (sql.Result, error) {
	d.Log.Println("Unlocking tables")
	return d.DB.Exec(fmt.Sprintf("UNLOCK TABLES"))
}

// Get list of existing tables in database
func (d *mySQL) GetTables() (tables []string, err error) {
	tables = make([]string, 0)
	var rows *sql.Rows
	if rows, err = d.DB.Query("SHOW FULL TABLES"); err != nil {
		return
	}
	defer rows.Close()
	for rows.Next() {
		var tableName, tableType string
		if err = rows.Scan(&tableName, &tableType); err != nil {
			return
		}
		if tableType == "BASE TABLE" {
			tables = append(tables, tableName)
		}
	}
	return
}

// Dump the script to create the table
func (d *mySQL) DumpCreateTable(w io.Writer, table string) error {
	d.Log.Println("Dumping structure for table", table)
	fmt.Fprintf(w, "\n--\n-- Structure for table `%s`\n--\n\n", table)
	fmt.Fprintf(w, "DROP TABLE IF EXISTS `%s`;\n", table)
	row := d.DB.QueryRow(fmt.Sprintf("SHOW CREATE TABLE `%s`", table))
	var tname, ddl string
	if err := row.Scan(&tname, &ddl); err != nil {
		return err
	}
	fmt.Fprintf(w, "%s;\n", ddl)
	return nil
}

// Get the column list for the SELECT, applying the select map from config file.
func (d *mySQL) GetColumnsForSelect(table string) (columns []string, err error) {
	var rows *sql.Rows
	if rows, err = d.DB.Query(fmt.Sprintf("SELECT * FROM `%s` LIMIT 1", table)); err != nil {
		return
	}
	defer rows.Close()
	if columns, err = rows.Columns(); err != nil {
		return
	}
	for k, column := range columns {
		replacement, ok := d.SelectMap[table][column]
		if ok {
			columns[k] = fmt.Sprintf("%s AS `%s`", replacement, column)
		} else {
			columns[k] = fmt.Sprintf("`%s`", column)
		}
	}
	return
}

// Get the complete SELECT query to fetch data from database
func (d *mySQL) GetSelectQueryFor(table string) (query string, err error) {
	cols, err := d.GetColumnsForSelect(table)
	if err != nil {
		return "", err
	}
	query = fmt.Sprintf("SELECT %s FROM `%s`", strings.Join(cols, ", "), table)
	if where, ok := d.WhereMap[table]; ok {
		query = fmt.Sprintf("%s WHERE %s", query, where)
	}
	return
}

// Get the number of rows the select will return
func (d *mySQL) GetRowCount(table string) (count uint64, err error) {
	query := fmt.Sprintf("SELECT COUNT(*) FROM `%s`", table)
	if where, ok := d.WhereMap[table]; ok {
		query = fmt.Sprintf("%s WHERE %s", query, where)
	}
	row := d.DB.QueryRow(query)
	if err = row.Scan(&count); err != nil {
		return
	}
	return
}

// Dump comments including table name and row count to w
func (d *mySQL) DumpTableHeader(w io.Writer, table string) (count uint64, err error) {
	fmt.Fprintf(w, "\n--\n-- Data for table `%s`", table)
	if count, err = d.GetRowCount(table); err != nil {
		return
	}
	fmt.Fprintf(w, " -- %d rows\n--\n\n", count)
	return
}

// Write the query to lock writes in the specified table
func (d *mySQL) DumpTableLockWrite(w io.Writer, table string) {
	fmt.Fprintf(w, "LOCK TABLES `%s` WRITE;\n", table)
}

// Write the query to unlock tables
func (d *mySQL) DumpUnlockTables(w io.Writer) {
	fmt.Fprintln(w, "UNLOCK TABLES;")
}

func (d *mySQL) selectAllDataFor(table string) (rows *sql.Rows, columns []string, err error) {
	var selectQuery string
	if selectQuery, err = d.GetSelectQueryFor(table); err != nil {
		return
	}
	if rows, err = d.DB.Query(selectQuery); err != nil {
		return
	}
	if columns, err = rows.Columns(); err != nil {
		return
	}
	return
}

// Get the table data
func (d *mySQL) DumpTableData(w io.Writer, table string) (err error) {
	d.Log.Println("Dumping data for table", table)
	rows, columns, err := d.selectAllDataFor(table)
	if err != nil {
		return
	}
	defer rows.Close()

	values := make([]*sql.RawBytes, len(columns))
	scanArgs := make([]interface{}, len(values))
	for i := range values {
		scanArgs[i] = &values[i]
	}

	query := fmt.Sprintf("INSERT INTO `%s` VALUES", table)
	var data []string
	for rows.Next() {
		if err = rows.Scan(scanArgs...); err != nil {
			return err
		}
		var vals []string
		for _, col := range values {
			val := "NULL"
			if col != nil {
				val = fmt.Sprintf("'%s'", escape(string(*col)))
			}
			vals = append(vals, val)
		}

		data = append(data, fmt.Sprintf("( %s )", strings.Join(vals, ", ")))
		if len(data) >= d.ExtendedInsertRows {
			fmt.Fprintf(w, "%s\n%s;\n", query, strings.Join(data, ",\n"))
			data = make([]string, 0)
		}
	}

	if len(data) > 0 {
		fmt.Fprintf(w, "%s\n%s;\n", query, strings.Join(data, ",\n"))
	}

	return
}

func (d *mySQL) Dump(w io.Writer) (err error) {
	fmt.Fprintf(w, "SET NAMES utf8;\n")
	fmt.Fprintf(w, "SET FOREIGN_KEY_CHECKS = 0;\n")

	d.Log.Println("Getting table list...")
	tables, err := d.GetTables()
	if err != nil {
		return
	}

	for _, table := range tables {
		if d.FilterMap[table] != "ignore" {
			skipData := d.FilterMap[table] == "nodata"
			if !skipData && d.UseTableLock {
				d.LockTableReading(table)
				d.FlushTable(table)
			}
			d.DumpCreateTable(w, table)
			if !skipData {
				cnt, err := d.DumpTableHeader(w, table)
				if err != nil {
					return err
				}
				if cnt > 0 {
					d.DumpTableLockWrite(w, table)
					d.DumpTableData(w, table)
					fmt.Fprintln(w)
					d.DumpUnlockTables(w)
					if d.UseTableLock {
						d.UnlockTables()
					}
				}
			}
		}
	}

	fmt.Fprintf(w, "SET FOREIGN_KEY_CHECKS = 1;\n")
	return
}
<commit_msg>Update mysql.go<commit_after>package dumper

import (
	"database/sql"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"strings"
)

// ExtendedInsertDefaultRowCount: Default rows that will be dumped by each INSERT statement
const (
	ExtendedInsertDefaultRowCount = 100
)

type mySQL struct {
	DB                 *sql.DB
	SelectMap          map[string]map[string]string
	WhereMap           map[string]string
	FilterMap          map[string]string
	UseTableLock       bool
	Log                *log.Logger
	ExtendedInsertRows int
}

// NewMySQLDumper is the constructor
func NewMySQLDumper(db *sql.DB, logger *log.Logger) *mySQL {
	if logger == nil {
		logger = log.New(ioutil.Discard, "", 0)
	}
	return &mySQL{DB: db, Log: logger, ExtendedInsertRows: ExtendedInsertDefaultRowCount}
}

// Lock the table (read only)
func (d *mySQL) LockTableReading(table string) (sql.Result, error) {
	d.Log.Println("Locking table", table, "for reading")
	return d.DB.Exec(fmt.Sprintf("LOCK TABLES `%s` READ", table))
}

// Flush table to ensure that the all active index pages are written to disk
func (d *mySQL) FlushTable(table string) (sql.Result, error) {
	d.Log.Println("Flushing table", table)
	return d.DB.Exec(fmt.Sprintf("FLUSH TABLES `%s`", table))
}

// Release the global read locks
func (d *mySQL) UnlockTables() (sql.Result, error) {
	d.Log.Println("Unlocking tables")
	return d.DB.Exec(fmt.Sprintf("UNLOCK TABLES"))
}

// Get list of existing tables in database
func (d *mySQL) GetTables() (tables []string, err error) {
	tables = make([]string, 0)
	var rows *sql.Rows
	if rows, err = d.DB.Query("SHOW FULL TABLES"); err != nil {
		return
	}
	defer rows.Close()
	for rows.Next() {
		var tableName, tableType string
		if err = rows.Scan(&tableName, &tableType); err != nil {
			return
		}
		if tableType == "BASE TABLE" {
			tables = append(tables, tableName)
		}
	}
	return
}

// Dump the script to create the table
func (d *mySQL) DumpCreateTable(w io.Writer, table string) error {
	d.Log.Println("Dumping structure for table", table)
	fmt.Fprintf(w, "\n--\n-- Structure for table `%s`\n--\n\n", table)
	fmt.Fprintf(w, "DROP TABLE IF EXISTS `%s`;\n", table)
	row := d.DB.QueryRow(fmt.Sprintf("SHOW CREATE TABLE `%s`", table))
	var tname, ddl string
	if err := row.Scan(&tname, &ddl); err != nil {
		return err
	}
	fmt.Fprintf(w, "%s;\n", ddl)
	return nil
}

// Get the column list for the SELECT, applying the select map from config file.
func (d *mySQL) GetColumnsForSelect(table string) (columns []string, err error) {
	var rows *sql.Rows
	if rows, err = d.DB.Query(fmt.Sprintf("SELECT * FROM `%s` LIMIT 1", table)); err != nil {
		return
	}
	defer rows.Close()
	if columns, err = rows.Columns(); err != nil {
		return
	}
	for k, column := range columns {
		replacement, ok := d.SelectMap[strings.ToLower(table)][column]
		if ok {
			columns[k] = fmt.Sprintf("%s AS `%s`", replacement, column)
		} else {
			columns[k] = fmt.Sprintf("`%s`", column)
		}
	}
	return
}

// Get the complete SELECT query to fetch data from database
func (d *mySQL) GetSelectQueryFor(table string) (query string, err error) {
	cols, err := d.GetColumnsForSelect(table)
	if err != nil {
		return "", err
	}
	query = fmt.Sprintf("SELECT %s FROM `%s`", strings.Join(cols, ", "), table)
	if where, ok := d.WhereMap[strings.ToLower(table)]; ok {
		query = fmt.Sprintf("%s WHERE %s", query, where)
	}
	return
}

// Get the number of rows the select will return
func (d *mySQL) GetRowCount(table string) (count uint64, err error) {
	query := fmt.Sprintf("SELECT COUNT(*) FROM `%s`", table)
	if where, ok := d.WhereMap[strings.ToLower(table)]; ok {
		query = fmt.Sprintf("%s WHERE %s", query, where)
	}
	row := d.DB.QueryRow(query)
	if err = row.Scan(&count); err != nil {
		return
	}
	return
}

// Dump comments including table name and row count to w
func (d *mySQL) DumpTableHeader(w io.Writer, table string) (count uint64, err error) {
	fmt.Fprintf(w, "\n--\n-- Data for table `%s`", table)
	if count, err = d.GetRowCount(table); err != nil {
		return
	}
	fmt.Fprintf(w, " -- %d rows\n--\n\n", count)
	return
}

// Write the query to lock writes in the specified table
func (d *mySQL) DumpTableLockWrite(w io.Writer, table string) {
	fmt.Fprintf(w, "LOCK TABLES `%s` WRITE;\n", table)
}

// Write the query to unlock tables
func (d *mySQL) DumpUnlockTables(w io.Writer) {
	fmt.Fprintln(w, "UNLOCK TABLES;")
}

func (d *mySQL) selectAllDataFor(table string) (rows *sql.Rows, columns []string, err error) {
	var selectQuery string
	if selectQuery, err = d.GetSelectQueryFor(table); err != nil {
		return
	}
	if rows, err = d.DB.Query(selectQuery); err != nil {
		return
	}
	if columns, err = rows.Columns(); err != nil {
		return
	}
	return
}

// Get the table data
func (d *mySQL) DumpTableData(w io.Writer, table string) (err error) {
	d.Log.Println("Dumping data for table", table)
	rows, columns, err := d.selectAllDataFor(table)
	if err != nil {
		return
	}
	defer rows.Close()

	values := make([]*sql.RawBytes, len(columns))
	scanArgs := make([]interface{}, len(values))
	for i := range values {
		scanArgs[i] = &values[i]
	}

	query := fmt.Sprintf("INSERT INTO `%s` VALUES", table)
	var data []string
	for rows.Next() {
		if err = rows.Scan(scanArgs...); err != nil {
			return err
		}
		var vals []string
		for _, col := range values {
			val := "NULL"
			if col != nil {
				val = fmt.Sprintf("'%s'", escape(string(*col)))
			}
			vals = append(vals, val)
		}

		data = append(data, fmt.Sprintf("( %s )", strings.Join(vals, ", ")))
		if len(data) >= d.ExtendedInsertRows {
			fmt.Fprintf(w, "%s\n%s;\n", query, strings.Join(data, ",\n"))
			data = make([]string, 0)
		}
	}

	if len(data) > 0 {
		fmt.Fprintf(w, "%s\n%s;\n", query, strings.Join(data, ",\n"))
	}

	return
}

func (d *mySQL) Dump(w io.Writer) (err error) {
	fmt.Fprintf(w, "SET NAMES utf8;\n")
	fmt.Fprintf(w, "SET FOREIGN_KEY_CHECKS = 0;\n")

	d.Log.Println("Getting table list...")
	tables, err := d.GetTables()
	if err != nil {
		return
	}

	for _, table := range tables {
		if d.FilterMap[strings.ToLower(table)] != "ignore" {
			skipData := d.FilterMap[strings.ToLower(table)] == "nodata"
			if !skipData && d.UseTableLock {
				d.LockTableReading(table)
				d.FlushTable(table)
			}
			d.DumpCreateTable(w, table)
			if !skipData {
				cnt, err := d.DumpTableHeader(w, table)
				if err != nil {
					return err
				}
				if cnt > 0 {
					d.DumpTableLockWrite(w, table)
					d.DumpTableData(w, table)
					fmt.Fprintln(w)
					d.DumpUnlockTables(w)
					if d.UseTableLock {
						d.UnlockTables()
					}
				}
			}
		}
	}

	fmt.Fprintf(w, "SET FOREIGN_KEY_CHECKS = 1;\n")
	return
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Mark Samman <https://github.com/marksamman/bencode>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package bencode

import (
	"bufio"
	"bytes"
	"fmt"
	"math"
	"testing"
)

func TestEncodeSinglefileTorrentBencode(t *testing.T) {
	dict := make(map[string]interface{})
	dict["announce"] = "http://bttracker.debian.org:6969/announce"
	dict["comment"] = "\"Debian CD from cdimage.debian.org\""
	dict["creation date"] = 1391870037
	dict["httpseeds"] = []interface{}{
		"http://cdimage.debian.org/cdimage/release/7.4.0/iso-cd/debian-7.4.0-amd64-netinst.iso",
		"http://cdimage.debian.org/cdimage/archive/7.4.0/iso-cd/debian-7.4.0-amd64-netinst.iso",
	}

	infoDict := make(map[string]interface{})
	infoDict["length"] = 232783872
	infoDict["name"] = "debian-7.4.0-amd64-netinst.iso"
	infoDict["piece length"] = 262144
	infoDict["pieces"] = ""
	dict["info"] = infoDict

	res := string(Encode(dict))
	expected := "d8:announce41:http://bttracker.debian.org:6969/announce7:comment35:\"Debian CD from cdimage.debian.org\"13:creation datei1391870037e9:httpseedsl85:http://cdimage.debian.org/cdimage/release/7.4.0/iso-cd/debian-7.4.0-amd64-netinst.iso85:http://cdimage.debian.org/cdimage/archive/7.4.0/iso-cd/debian-7.4.0-amd64-netinst.isoe4:infod6:lengthi232783872e4:name30:debian-7.4.0-amd64-netinst.iso12:piece lengthi262144e6:pieces0:ee"
	if res != expected {
		t.Error(fmt.Sprintf("expected %s\ngot %s", expected, res))
	}
}

func TestEncodeListOfInts(t *testing.T) {
	dict := make(map[string]interface{})
	list := []interface{}{}
	list = append(list, int8(math.MinInt8))
	list = append(list, uint8(math.MaxUint8))
	list = append(list, int16(math.MinInt16))
	list = append(list, uint16(math.MaxUint16))
	list = append(list, int32(math.MinInt32))
	list = append(list, uint32(math.MaxUint32))
	list = append(list, int64(math.MinInt64))
	list = append(list, uint64(math.MaxUint64))
	list = append(list, int(-1))
	list = append(list, int(0))
	list = append(list, int(1))
	dict["integers"] = list

	res := string(Encode(dict))
	expected := "d8:integersl"
	expected += fmt.Sprintf("i%de", math.MinInt8)
	expected += fmt.Sprintf("i%de", math.MaxUint8)
	expected += fmt.Sprintf("i%de", math.MinInt16)
	expected += fmt.Sprintf("i%de", math.MaxUint16)
	expected += fmt.Sprintf("i%de", math.MinInt32)
	expected += fmt.Sprintf("i%de", uint32(math.MaxUint32))
	expected += fmt.Sprintf("i%de", int64(math.MinInt64))
	expected += fmt.Sprintf("i%de", uint64(math.MaxUint64))
	expected += "i-1e"
	expected += "i0e"
	expected += "i1e"
	expected += "ee"
	if res != expected {
		t.Error(fmt.Sprintf("expected %s\ngot %s", expected, res))
	}
}

func TestEncodeKeySortingOrder(t *testing.T) {
	dict := map[string]interface{}{
		"Abe": 1,
		"abe": 1,
		"abé": 1,
		"Ábe": 1,
		"ábe": 1,
		"Äbe": 1,
		"äbe": 1,
		"Oeb": 1,
		"oeb": 1,
		"Ôeb": 1,
		"ôeb": 1,
	}

	decoder := decoder{*bufio.NewReader(bytes.NewReader(Encode(dict)))}
	decoder.ReadByte() // skip 'd'

	expectedOrder := []string{"Abe", "Oeb", "abe", "abé", "oeb", "Ábe", "Äbe", "Ôeb", "ábe", "äbe", "ôeb"}
	for index, expected := range expectedOrder {
		if str, err := decoder.readString(); err != nil {
			t.Error(err)
		} else if str != expected {
			t.Errorf("wrong order, expected: %s, got: %s at index %d", expected, str, index)
		}

		if b, err := decoder.ReadByte(); err != nil {
			t.Error(err)
		} else if _, err := decoder.readInterfaceType(b); err != nil {
			t.Error(err)
		}
	}
}
<commit_msg>Use t.Errorf instead of t.Error+fmt.Sprintf<commit_after>/*
 * Copyright (c) 2014 Mark Samman <https://github.com/marksamman/bencode>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package bencode

import (
	"bufio"
	"bytes"
	"fmt"
	"math"
	"testing"
)

func TestEncodeSinglefileTorrentBencode(t *testing.T) {
	dict := make(map[string]interface{})
	dict["announce"] = "http://bttracker.debian.org:6969/announce"
	dict["comment"] = "\"Debian CD from cdimage.debian.org\""
	dict["creation date"] = 1391870037
	dict["httpseeds"] = []interface{}{
		"http://cdimage.debian.org/cdimage/release/7.4.0/iso-cd/debian-7.4.0-amd64-netinst.iso",
		"http://cdimage.debian.org/cdimage/archive/7.4.0/iso-cd/debian-7.4.0-amd64-netinst.iso",
	}

	infoDict := make(map[string]interface{})
	infoDict["length"] = 232783872
	infoDict["name"] = "debian-7.4.0-amd64-netinst.iso"
	infoDict["piece length"] = 262144
	infoDict["pieces"] = ""
	dict["info"] = infoDict

	res := string(Encode(dict))
	expected := "d8:announce41:http://bttracker.debian.org:6969/announce7:comment35:\"Debian CD from cdimage.debian.org\"13:creation datei1391870037e9:httpseedsl85:http://cdimage.debian.org/cdimage/release/7.4.0/iso-cd/debian-7.4.0-amd64-netinst.iso85:http://cdimage.debian.org/cdimage/archive/7.4.0/iso-cd/debian-7.4.0-amd64-netinst.isoe4:infod6:lengthi232783872e4:name30:debian-7.4.0-amd64-netinst.iso12:piece lengthi262144e6:pieces0:ee"
	if res != expected {
		t.Errorf("expected %s\ngot %s", expected, res)
	}
}

func TestEncodeListOfInts(t *testing.T) {
	dict := make(map[string]interface{})
	list := []interface{}{}
	list = append(list, int8(math.MinInt8))
	list = append(list, uint8(math.MaxUint8))
	list = append(list, int16(math.MinInt16))
	list = append(list, uint16(math.MaxUint16))
	list = append(list, int32(math.MinInt32))
	list = append(list, uint32(math.MaxUint32))
	list = append(list, int64(math.MinInt64))
	list = append(list, uint64(math.MaxUint64))
	list = append(list, int(-1))
	list = append(list, int(0))
	list = append(list, int(1))
	dict["integers"] = list

	res := string(Encode(dict))
	expected := "d8:integersl"
	expected += fmt.Sprintf("i%de", math.MinInt8)
	expected += fmt.Sprintf("i%de", math.MaxUint8)
	expected += fmt.Sprintf("i%de", math.MinInt16)
	expected += fmt.Sprintf("i%de", math.MaxUint16)
	expected += fmt.Sprintf("i%de", math.MinInt32)
	expected += fmt.Sprintf("i%de", uint32(math.MaxUint32))
	expected += fmt.Sprintf("i%de", int64(math.MinInt64))
	expected += fmt.Sprintf("i%de", uint64(math.MaxUint64))
	expected += "i-1e"
	expected += "i0e"
	expected += "i1e"
	expected += "ee"
	if res != expected {
		t.Errorf("expected %s\ngot %s", expected, res)
	}
}

func TestEncodeKeySortingOrder(t *testing.T) {
	dict := map[string]interface{}{
		"Abe": 1,
		"abe": 1,
		"abé": 1,
		"Ábe": 1,
		"ábe": 1,
		"Äbe": 1,
		"äbe": 1,
		"Oeb": 1,
		"oeb": 1,
		"Ôeb": 1,
		"ôeb": 1,
	}

	decoder := decoder{*bufio.NewReader(bytes.NewReader(Encode(dict)))}
	decoder.ReadByte() // skip 'd'

	expectedOrder := []string{"Abe", "Oeb", "abe", "abé", "oeb", "Ábe", "Äbe", "Ôeb", "ábe", "äbe", "ôeb"}
	for index, expected := range expectedOrder {
		if str, err := decoder.readString(); err != nil {
			t.Error(err)
		} else if str != expected {
			t.Errorf("wrong order, expected: %s, got: %s at index %d", expected, str, index)
		}

		if b, err := decoder.ReadByte(); err != nil {
			t.Error(err)
		} else if _, err := decoder.readInterfaceType(b); err != nil {
			t.Error(err)
		}
	}
}
<|endoftext|>


<commit_before>package envetcd

import (
	"os"
	"testing"

	"github.com/coreos/etcd/pkg/transport"
	"github.com/coreos/go-etcd/etcd"
	"github.com/zvelo/zvelo-services/util"

	. "github.com/smartystreets/goconvey/convey"
)

var (
	config *Config
)

func init() {
	util.InitLogger("WARN")

	// $ETCD_ENDPOINT should look like "http://127.0.0.1:4001"

	config = &Config{
		Peers:    []string{os.Getenv("ETCD_ENDPOINT")},
		Prefix:   "/config",
		Hostname: "env",
		Sync:     false,
		System:   "systemtest",
		Service:  "servicetest",
		TLS:      &transport.TLSInfo{},
	}
}

func TestEtcd(t *testing.T) {
	Convey("When getting keys from etcd", t, func() {
		So(os.Getenv("ETCD_ENDPOINT"), ShouldNotBeEmpty)

		client := etcd.NewClient(config.Peers)
		client.SetDir("/config/system/systemtest", 0)
		client.SetDir("/config/service/servicetest", 0)
		client.Set("/config/global/systemtest/testKey", "globaltestVal", 0)
		client.Set("/config/host/env", "", 0)

		Convey("config should be valid", func() {
			So(config.Prefix, ShouldEqual, "/config")
			So(config.Hostname, ShouldEqual, "env")
			So(config.Sync, ShouldBeFalse)
			So(config.System, ShouldEqual, "systemtest")
			So(config.Service, ShouldEqual, "servicetest")
			So(config.Peers, ShouldNotBeEmpty)
			So(config.TLS, ShouldNotBeNil)

			Convey("massagePeers should work", func() {
				peersOrig := config.Peers
				config.Peers = []string{"127.0.0.1:4001", "http://127.0.0.1:4001"}
				defer func() { config.Peers = peersOrig }()

				So(massagePeers(config), ShouldBeNil)
				So(len(config.Peers), ShouldEqual, 2)
				So(config.Peers[0], ShouldEqual, "http://127.0.0.1:4001")
				So(config.Peers[1], ShouldEqual, "http://127.0.0.1:4001")

				config.Peers = []string{":"}
				err := massagePeers(config)
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "parse :: missing protocol scheme")

			})

			Convey("getClient should return an etcd client based on a given config", func() {
				etcdClient, err := getClient(config)
				So(err, ShouldBeNil)
				So(etcdClient, ShouldNotBeEmpty)
				So(etcdClient.CheckRetry, ShouldBeNil)

				Convey("getKeyPairs returns keypairs", func() {
					keyPairs, err := GetKeyPairs(config)
					So(err, ShouldBeNil)
					So(keyPairs, ShouldNotBeEmpty)
				})

				Convey("Testing override keys", func() {
					Convey("Setting /config/global testkey only", func() {
						client.Set("/config/global/systemtest/testKey", "globaltestVal", 0)
						keyPairs, err := GetKeyPairs(config)
						So(err, ShouldBeNil)

						_, isExisting := keyPairs["systemtest_testKey"]
						So(isExisting, ShouldBeTrue)
						So(keyPairs["systemtest_testKey"], ShouldEqual, "globaltestVal")

					})

					Convey("Setting /config/global/testKey", func() {
						client.Set("/config/global/systemtest/testKey", "globaltestVal", 0)
						client.Set("/config/global/testKey", "testGlobalVal2", 0)
						keyPairs, err := GetKeyPairs(config)
						So(err, ShouldBeNil)

						_, isExisting := keyPairs["testKey"]
						So(isExisting, ShouldBeTrue)
						So(keyPairs["systemtest_testKey"], ShouldEqual, "globaltestVal")
						So(keyPairs["testKey"], ShouldEqual, "testGlobalVal2")
					})

					Convey("Setting /config/system/systemtest/testKey should override the global testKey", func() {
						client.Set("/config/global/systemtest/testKey", "globaltestVal", 0)
						client.Set("/config/global/testKey", "testGlobalVal2", 0)
						client.Set("/config/system/systemtest/testKey", "testsystemVal", 0)
						keyPairs, err := GetKeyPairs(config)
						So(err, ShouldBeNil)
						_, isExisting := keyPairs["testKey"]

						So(isExisting, ShouldBeTrue)
						So(keyPairs["systemtest_testKey"], ShouldEqual, "globaltestVal")
						So(keyPairs["testKey"], ShouldEqual, "testsystemVal")
					})
				})

				Convey("Setting /config/service/systemtest/testserviceKey should not be in the keypair", func() {
					client.Set("/config/service/systemtest/testserviceKey", "testserviceVal", 0)
					keyPairs, err := GetKeyPairs(config)
					So(err, ShouldBeNil)

					_, isExisting := keyPairs["testserviceKey"]
					So(isExisting, ShouldBeFalse)
					So(keyPairs["systemtest_testKey"], ShouldEqual, "globaltestVal")
					So(keyPairs["testserviceKey"], ShouldBeEmpty)

					client.Delete("/config", true)
				})

				Convey("Testing nested keys", func() {
					Convey("Adding key-value pairs in systemtest root /config/system/systemtest/", func() {
						client.Set("/config/system/systemtest/nestkey1", "nestval1", 0)
						client.Set("/config/system/systemtest/nestkey2", "nestval2", 0)
						keyPairs, err := GetKeyPairs(config)
						So(err, ShouldBeNil)

						_, isExisting := keyPairs["nestkey1"]
						So(isExisting, ShouldBeTrue)
						So(keyPairs["nestkey1"], ShouldEqual, "nestval1")

						_, isExisting = keyPairs["nestkey2"]
						So(isExisting, ShouldBeTrue)
						So(keyPairs["nestkey2"], ShouldEqual, "nestval2")

						Convey("Adding key-value pairs in systemtest first nest directory /config/system/systemtest/nest1/", func() {
							client.Set("/config/system/systemtest/nest1/nest1key1", "nest1val1", 0)
							client.Set("/config/system/systemtest/nest1/nest1key2", "nest1val2", 0)
							client.Set("/config/system/systemtest/nest2/nest2key1", "nest2val1", 0)
							client.Set("/config/system/systemtest/nest2/nest2key2", "nest2val2", 0)
							keyPairs, err := GetKeyPairs(config)
							So(err, ShouldBeNil)

							_, isExisting = keyPairs["nest1_nest1key1"]
							So(isExisting, ShouldBeTrue)
							So(keyPairs["nest1_nest1key1"], ShouldEqual, "nest1val1")

							_, isExisting = keyPairs["nest1_nest1key2"]
							So(isExisting, ShouldBeTrue)
							So(keyPairs["nest1_nest1key2"], ShouldEqual, "nest1val2")

							_, isExisting = keyPairs["nest2_nest2key1"]
							So(isExisting, ShouldBeTrue)
							So(keyPairs["nest2_nest2key1"], ShouldEqual, "nest2val1")

							_, isExisting = keyPairs["nest1_nest1key2"]
							So(isExisting, ShouldBeTrue)
							So(keyPairs["nest2_nest2key2"], ShouldEqual, "nest2val2")

							Convey("Adding key-value pairs in systemtest second nest directory /config/system/systemtest/nest1/nest2", func() {
								client.Set("/config/system/systemtest/nest1/nest2/nest2key1", "nest2val1", 0)
								client.Set("/config/system/systemtest/nest1/nest2/nest2key2", "nest2val2", 0)
								keyPairs, err := GetKeyPairs(config)
								So(err, ShouldBeNil)

								_, isExisting = keyPairs["nest1_nest2_nest2key1"]
								So(isExisting, ShouldBeTrue)
								So(keyPairs["nest1_nest2_nest2key1"], ShouldEqual, "nest2val1")

								_, isExisting = keyPairs["nest1_nest2_nest2key1"]
								So(isExisting, ShouldBeTrue)
								So(keyPairs["nest1_nest2_nest2key2"], ShouldEqual, "nest2val2")

								client.Delete("/config", true)
							})
						})
					})
				})
			})
		})
	})
}
<commit_msg>add some test debugging for circle<commit_after>package envetcd

import (
	"fmt"
	"os"
	"testing"

	"github.com/coreos/etcd/pkg/transport"
	"github.com/coreos/go-etcd/etcd"
	"github.com/zvelo/zvelo-services/util"

	. "github.com/smartystreets/goconvey/convey"
)

var (
	config *Config
)

func init() {
	util.InitLogger("WARN")

	// $ETCD_ENDPOINT should look like "http://127.0.0.1:4001"

	config = &Config{
		Peers:    []string{os.Getenv("ETCD_ENDPOINT")},
		Prefix:   "/config",
		Hostname: "env",
		Sync:     false,
		System:   "systemtest",
		Service:  "servicetest",
		TLS:      &transport.TLSInfo{},
	}
}

func TestEtcd(t *testing.T) {
	Convey("When getting keys from etcd", t, func() {
		So(os.Getenv("ETCD_ENDPOINT"), ShouldNotBeEmpty)

		client := etcd.NewClient(config.Peers)
		client.SetDir("/config/system/systemtest", 0)
		client.SetDir("/config/service/servicetest", 0)
		client.Set("/config/global/systemtest/testKey", "globaltestVal", 0)
		client.Set("/config/host/env", "", 0)

		Convey("config should be valid", func() {
			So(config.Prefix, ShouldEqual, "/config")
			So(config.Hostname, ShouldEqual, "env")
			So(config.Sync, ShouldBeFalse)
			So(config.System, ShouldEqual, "systemtest")
			So(config.Service, ShouldEqual, "servicetest")
			So(config.Peers, ShouldNotBeEmpty)
			So(config.TLS, ShouldNotBeNil)

			Convey("massagePeers should work", func() {
				peersOrig := config.Peers
				config.Peers = []string{"127.0.0.1:4001", "http://127.0.0.1:4001"}
				defer func() { config.Peers = peersOrig }()

				So(massagePeers(config), ShouldBeNil)
				So(len(config.Peers), ShouldEqual, 2)
				So(config.Peers[0], ShouldEqual, "http://127.0.0.1:4001")
				So(config.Peers[1], ShouldEqual, "http://127.0.0.1:4001")

				config.Peers = []string{":"}
				err := massagePeers(config)
				So(err, ShouldNotBeNil)
				So(err.Error(), ShouldEqual, "parse :: missing protocol scheme")

			})

			Convey("getClient should return an etcd client based on a given config", func() {
				etcdClient, err := getClient(config)
				So(err, ShouldBeNil)
				So(etcdClient, ShouldNotBeEmpty)
				So(etcdClient.CheckRetry, ShouldBeNil)

				Convey("getKeyPairs returns keypairs", func() {
					keyPairs, err := GetKeyPairs(config)
					So(err, ShouldBeNil)
					So(keyPairs, ShouldNotBeEmpty)
				})

				Convey("Testing override keys", func() {
					Convey("Setting /config/global testkey only", func() {
						client.Set("/config/global/systemtest/testKey", "globaltestVal", 0)
						keyPairs, err := GetKeyPairs(config)
						So(err, ShouldBeNil)

						fmt.Println("\n\n", keyPairs, "\n")

						_, isExisting := keyPairs["systemtest_testKey"]
						So(isExisting, ShouldBeTrue)
						So(keyPairs["systemtest_testKey"], ShouldEqual, "globaltestVal")

					})

					Convey("Setting /config/global/testKey", func() {
						client.Set("/config/global/systemtest/testKey", "globaltestVal", 0)
						client.Set("/config/global/testKey", "testGlobalVal2", 0)
						keyPairs, err := GetKeyPairs(config)
						So(err, ShouldBeNil)

						_, isExisting := keyPairs["testKey"]
						So(isExisting, ShouldBeTrue)
						So(keyPairs["systemtest_testKey"], ShouldEqual, "globaltestVal")
						So(keyPairs["testKey"], ShouldEqual, "testGlobalVal2")
					})

					Convey("Setting /config/system/systemtest/testKey should override the global testKey", func() {
						client.Set("/config/global/systemtest/testKey", "globaltestVal", 0)
						client.Set("/config/global/testKey", "testGlobalVal2", 0)
						client.Set("/config/system/systemtest/testKey", "testsystemVal", 0)
						keyPairs, err := GetKeyPairs(config)
						So(err, ShouldBeNil)
						_, isExisting := keyPairs["testKey"]

						So(isExisting, ShouldBeTrue)
						So(keyPairs["systemtest_testKey"], ShouldEqual, "globaltestVal")
						So(keyPairs["testKey"], ShouldEqual, "testsystemVal")
					})
				})

				Convey("Setting /config/service/systemtest/testserviceKey should not be in the keypair", func() {
					client.Set("/config/service/systemtest/testserviceKey", "testserviceVal", 0)
					keyPairs, err := GetKeyPairs(config)
					So(err, ShouldBeNil)

					_, isExisting := keyPairs["testserviceKey"]
					So(isExisting, ShouldBeFalse)
					So(keyPairs["systemtest_testKey"], ShouldEqual, "globaltestVal")
					So(keyPairs["testserviceKey"], ShouldBeEmpty)

					client.Delete("/config", true)
				})

				Convey("Testing nested keys", func() {
					Convey("Adding key-value pairs in systemtest root /config/system/systemtest/", func() {
						client.Set("/config/system/systemtest/nestkey1", "nestval1", 0)
						client.Set("/config/system/systemtest/nestkey2", "nestval2", 0)
						keyPairs, err := GetKeyPairs(config)
						So(err, ShouldBeNil)

						_, isExisting := keyPairs["nestkey1"]
						So(isExisting, ShouldBeTrue)
						So(keyPairs["nestkey1"], ShouldEqual, "nestval1")

						_, isExisting = keyPairs["nestkey2"]
						So(isExisting, ShouldBeTrue)
						So(keyPairs["nestkey2"], ShouldEqual, "nestval2")

						Convey("Adding key-value pairs in systemtest first nest directory /config/system/systemtest/nest1/", func() {
							client.Set("/config/system/systemtest/nest1/nest1key1", "nest1val1", 0)
							client.Set("/config/system/systemtest/nest1/nest1key2", "nest1val2", 0)
							client.Set("/config/system/systemtest/nest2/nest2key1", "nest2val1", 0)
							client.Set("/config/system/systemtest/nest2/nest2key2", "nest2val2", 0)
							keyPairs, err := GetKeyPairs(config)
							So(err, ShouldBeNil)

							_, isExisting = keyPairs["nest1_nest1key1"]
							So(isExisting, ShouldBeTrue)
							So(keyPairs["nest1_nest1key1"], ShouldEqual, "nest1val1")

							_, isExisting = keyPairs["nest1_nest1key2"]
							So(isExisting, ShouldBeTrue)
							So(keyPairs["nest1_nest1key2"], ShouldEqual, "nest1val2")

							_, isExisting = keyPairs["nest2_nest2key1"]
							So(isExisting, ShouldBeTrue)
							So(keyPairs["nest2_nest2key1"], ShouldEqual, "nest2val1")

							_, isExisting = keyPairs["nest1_nest1key2"]
							So(isExisting, ShouldBeTrue)
							So(keyPairs["nest2_nest2key2"], ShouldEqual, "nest2val2")

							Convey("Adding key-value pairs in systemtest second nest directory /config/system/systemtest/nest1/nest2", func() {
								client.Set("/config/system/systemtest/nest1/nest2/nest2key1", "nest2val1", 0)
								client.Set("/config/system/systemtest/nest1/nest2/nest2key2", "nest2val2", 0)
								keyPairs, err := GetKeyPairs(config)
								So(err, ShouldBeNil)

								_, isExisting = keyPairs["nest1_nest2_nest2key1"]
								So(isExisting, ShouldBeTrue)
								So(keyPairs["nest1_nest2_nest2key1"], ShouldEqual, "nest2val1")

								_, isExisting = keyPairs["nest1_nest2_nest2key1"]
								So(isExisting, ShouldBeTrue)
								So(keyPairs["nest1_nest2_nest2key2"], ShouldEqual, "nest2val2")

								client.Delete("/config", true)
							})
						})
					})
				})
			})
		})
	})
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/augustoroman/sandwich"
)

// Interface for abstracting out the user database.
type UserDb interface {
	Lookup(id string) (User, error)
}
type User struct{ Id, Name, Email string }

func main() {
	// To reduce log spam, we'll just put this here, not using any framework.
	http.Handle("/favicon.ico", http.NotFoundHandler())

	// Setup connections to the databases.
	udb := userDb{{"bob", "Bob", "bob@example.com"}, {"alice", "Alice", "alice@example.com"}}

	// Create a typical sandwich middleware with logging and error-handling.
	mw := sandwich.TheUsual().
		// Inject config and user database; now available to all handlers.
		ProvideAs(udb, (*UserDb)(nil)).
		// In this example, we'll always check to see if the user is logged in.
		// If so, we'll add a note to the log entries.
		With(ParseUserIfLoggedIn)

	// If the user is logged in, they'll get a personalized landing page.
	// Otherwise, they'll get a generic landing page.
	http.Handle("/", mw.With(ShowLandingPage))
	http.Handle("/login", mw.With(Login))

	// Some pages are only allowed if the user is logged in.
	http.Handle("/user/profile", mw.With(FailIfNotAuthenticated, ShowUserProfile))
	// If you have multiple pages that require authentication, you could do:
	//   authed := mw.With(FailIfNotAuthenticated)
	//   http.Handle("/user/profile", authed.With(ShowUserProfile))
	//   http.Handle("/user/...", authed.With(...))
	//   http.Handle("/user/...", authed.With(...))

	log.Println("Serving on :8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("Can't start webserver:", err)
	}
}

// The actual user DB implementation.
type userDb []User

func (udb userDb) Lookup(id string) (User, error) {
	for _, u := range udb {
		if id == u.Id {
			return u, nil
		}
	}
	return User{}, fmt.Errorf("no such user %q", id)
}

func ShowLandingPage(w http.ResponseWriter, u *User) {
	fmt.Fprintln(w, "")
	if u == nil {
		fmt.Fprint(w, "Hello unknown person!")
		fmt.Fprintf(w, "  [profile will fail and log an error]")
	} else {
		fmt.Fprintf(w, "Welcome back, %s!", u.Name)
		fmt.Fprintf(w, "  [profile]")
	}
	fmt.Fprintln(w, `

        Login

        <form action='/login'>
            <input type='text' name='id'>

            <input type='submit'>
        </form>

        Try logging in with:

 "alice" will authenticate to Alice

 "bob" will authenticate to Bob but panic during request handling

 any other string for a non-authenticated user.

    `)
}

func ShowUserProfile(w http.ResponseWriter, u User) {
	fmt.Fprintln(w, "")
	fmt.Fprintf(w, "Id: %s
Name: %s
Email:%s", u.Id, u.Name, u.Email)

	// Show an example of user-code panicking in a handler.
	if u.Id == "bob" {
		panic("oops")
	}
}

func Login(w http.ResponseWriter, r *http.Request, udb UserDb, e *sandwich.LogEntry) {
	u, err := udb.Lookup(r.FormValue("id"))
	if err != nil {
		log.Printf("No such user id: %q", r.FormValue("id"))
		http.SetCookie(w, &http.Cookie{Name: "auth", Value: "", Expires: time.Now()})
		http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
		return
	}

	e.Note["userId"] = u.Id
	http.SetCookie(w, &http.Cookie{
		Name:     "auth",
		Value:    u.Id, // Encrypt cookie here, maybe include the whole user struct.
		Expires:  time.Now().Add(time.Hour),
		MaxAge:   int(time.Hour / time.Second),
		HttpOnly: true,
	})
	http.Redirect(w, r, "/user/profile", http.StatusTemporaryRedirect)
}

func FailIfNotAuthenticated(u *User) (User, error) {
	if u == nil {
		return User{}, sandwich.Error{
			Code:      http.StatusUnauthorized,
			ClientMsg: "Not logged in",
			LogMsg:    "Unauthorized access attempt",
		}
	}
	return *u, nil
}

func getAndParseCookie(r *http.Request) (string, error) {
	c, err := r.Cookie("auth")
	if err != nil {
		return "", err
	}
	userid := c.Value // Decrypt cookie here, maybe getting a whole user struct.
	return userid, nil
}

func ParseUserIfLoggedIn(r *http.Request, udb UserDb, e *sandwich.LogEntry) (*User, error) {
	if user_id, err := getAndParseCookie(r); err != nil {
		return nil, nil // not logged in or expired or corrupt.  Ignore cookie.
	} else if user, err := udb.Lookup(user_id); err != nil {
		log.Printf("No such user: %q", user_id)
		return nil, nil // no such user
	} else {
		e.Note["userId"] = user.Id
		return &user, nil // Hello logged-in user!
	}
}
<commit_msg>Trivial doc wordsmithing in simple example.<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/augustoroman/sandwich"
)

// Interface for abstracting out the user database.
type UserDb interface {
	Lookup(id string) (User, error)
}
type User struct{ Id, Name, Email string }

func main() {
	// To reduce log spam, we'll just put this here, not using any framework.
	http.Handle("/favicon.ico", http.NotFoundHandler())

	// Setup connections to the databases.
	udb := userDb{{"bob", "Bob", "bob@example.com"}, {"alice", "Alice", "alice@example.com"}}

	// Create a typical sandwich middleware with logging and error-handling.
	mw := sandwich.TheUsual().
		// Inject config and user database; now available to all handlers.
		ProvideAs(udb, (*UserDb)(nil)).
		// In this example, we'll always check to see if the user is logged in.
		// If so, we'll add the user ID to the log entries.
		With(ParseUserIfLoggedIn)

	// If the user is logged in, they'll get a personalized landing page.
	// Otherwise, they'll get a generic landing page.
	http.Handle("/", mw.With(ShowLandingPage))
	http.Handle("/login", mw.With(Login))

	// Some pages are only allowed if the user is logged in.
	http.Handle("/user/profile", mw.With(FailIfNotAuthenticated, ShowUserProfile))
	// If you have multiple pages that require authentication, you could do:
	//   authed := mw.With(FailIfNotAuthenticated)
	//   http.Handle("/user/profile", authed.With(ShowUserProfile))
	//   http.Handle("/user/...", authed.With(...))
	//   http.Handle("/user/...", authed.With(...))

	log.Println("Serving on :8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal("Can't start webserver:", err)
	}
}

// The actual user DB implementation.
type userDb []User

func (udb userDb) Lookup(id string) (User, error) {
	for _, u := range udb {
		if id == u.Id {
			return u, nil
		}
	}
	return User{}, fmt.Errorf("no such user %q", id)
}

func ShowLandingPage(w http.ResponseWriter, u *User) {
	fmt.Fprintln(w, "")
	if u == nil {
		fmt.Fprint(w, "Hello unknown person!")
		fmt.Fprintf(w, "  [profile will fail and log an error]")
	} else {
		fmt.Fprintf(w, "Welcome back, %s!", u.Name)
		fmt.Fprintf(w, "  [profile]")
	}
	fmt.Fprintln(w, `

        Login

        <form action='/login'>
            <input type='text' name='id'>

            <input type='submit'>
        </form>

        Try logging in with:

 "alice" will authenticate to Alice

 "bob" will authenticate to Bob but panic during request handling

 any other string for a non-authenticated user.

    `)
}

func ShowUserProfile(w http.ResponseWriter, u User) {
	fmt.Fprintln(w, "")
	fmt.Fprintf(w, "Id: %s
Name: %s
Email:%s", u.Id, u.Name, u.Email)

	// Show an example of user-code panicking in a handler.
	if u.Id == "bob" {
		panic("oops")
	}
}

func Login(w http.ResponseWriter, r *http.Request, udb UserDb, e *sandwich.LogEntry) {
	u, err := udb.Lookup(r.FormValue("id"))
	if err != nil {
		log.Printf("No such user id: %q", r.FormValue("id"))
		http.SetCookie(w, &http.Cookie{Name: "auth", Value: "", Expires: time.Now()})
		http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
		return
	}

	e.Note["userId"] = u.Id
	http.SetCookie(w, &http.Cookie{
		Name:     "auth",
		Value:    u.Id, // Encrypt cookie here, maybe include the whole user struct.
		Expires:  time.Now().Add(time.Hour),
		MaxAge:   int(time.Hour / time.Second),
		HttpOnly: true,
	})
	http.Redirect(w, r, "/user/profile", http.StatusTemporaryRedirect)
}

func FailIfNotAuthenticated(u *User) (User, error) {
	if u == nil {
		return User{}, sandwich.Error{
			Code:      http.StatusUnauthorized,
			ClientMsg: "Not logged in",
			LogMsg:    "Unauthorized access attempt",
		}
	}
	return *u, nil
}

func getAndParseCookie(r *http.Request) (string, error) {
	c, err := r.Cookie("auth")
	if err != nil {
		return "", err
	}
	userid := c.Value // Decrypt cookie here, maybe getting a whole user struct.
	return userid, nil
}

func ParseUserIfLoggedIn(r *http.Request, udb UserDb, e *sandwich.LogEntry) (*User, error) {
	if user_id, err := getAndParseCookie(r); err != nil {
		return nil, nil // not logged in or expired or corrupt.  Ignore cookie.
	} else if user, err := udb.Lookup(user_id); err != nil {
		log.Printf("No such user: %q", user_id)
		return nil, nil // no such user
	} else {
		e.Note["userId"] = user.Id
		return &user, nil // Hello logged-in user!
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"github.com/stretchr/gomniauth"
	"github.com/stretchr/gomniauth/common"
	"github.com/stretchr/gomniauth/providers"
	"github.com/stretchr/goweb"
	"github.com/stretchr/goweb/context"
	"github.com/stretchr/stew/objects"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"time"
)

/*

  This is a full web-stack example showing how to use gomniauth.

	To run this app, just do:

	    clear; go build main.go; sudo ./main; rf main;

	NOTE: The domain is set to www.localhost.com, so you should route this
	      properly by editing your /etc/hosts file.

	Credit:

		The auth buttons were made by this guy:

			http://nicolasgallagher.com/lab/css3-social-signin-buttons/

*/

var Address string = ":80"

const (
	CookieNameSession string = "session"
)

// RedirectToLoginPage responds WithRedirect to the login page,
// passing the current page as the 'target' parameter.
var RedirectToLoginPage = func(c context.Context) error {
	redirectUrl := "login?target=" + c.HttpRequest().URL.Path
	log.Println("Example app: Redirecting to login page: %s", redirectUrl)
	return goweb.Respond.WithRedirect(c, redirectUrl)
}

func main() {

	/*
		Step 1. Create an AuthStore

			- An AuthStore is responsible for caching your auth tokens so you
			  don't have to send the user off to reauthenticate every time you
			  want to access their remote data.

	*/
	authStore := &ExampleAuthStore{make(map[string]*common.Auth)}

	/*
		Step 2. Create and configure an AuthManager

		  - Give it the authStore you created earlier
		  - Give it all the providers you wish to support, remember you'll
		    have to configure each provider for your application by specifying
		    Client ID, secrets, callback URLs and scopes etc. depending on the
		    auth type.

	*/
	authManager := gomniauth.NewManager(authStore,
		providers.Google("id", "secret", "http://www.localhost.com/auth/google/callback"),
		providers.Github("3d1e6ba69036e0624b61", "7e8938928d802e7582908a5eadaaaf22d64babf1", "http://www.localhost.com/auth/github/callback", "user"))

	// TODO: make the callback dynamic

	goweb.Map("GET", "/", func(c context.Context) error {

		return goweb.Respond.With(c, http.StatusOK, []byte(`

					<title>Welcome</title>

Omniauth Example Web app

							To get started, just try accessing this protected resource.

		`))

	})

	// GET /protected
	//
	// Attempts to get a protected resource.
	goweb.Map("GET", "/protected", func(c context.Context) error {

		log.Print("Example app: User tried to access protected resource")

		sessionCookie, sessionCookieErr := c.HttpRequest().Cookie(CookieNameSession)

		log.Printf("Example app: Cookies: %s", c.HttpRequest().Cookies())

		// do they have a session ID?
		if sessionCookie == nil || sessionCookieErr != nil {
			// no - they will need to login
			return RedirectToLoginPage(c)
		}

		segs := strings.Split(sessionCookie.Value, ":")
		providerName := segs[0]
		sessionId := segs[1]

		session := authManager.NewSession(sessionId, authManager.Provider(providerName))
		if authed, _ := session.IsAuthenticated(); !authed {
			// no - they will need to login
			return RedirectToLoginPage(c)
		}

		return goweb.Respond.With(c, http.StatusOK, []byte(`

					<title>Welcome</title>

Protected Resource

						You have successfully accessed the protected resource.

							Now you can log out

							Or you can expire the internal auth token

		`))
	})

	goweb.Map("GET", "/logout", func(c context.Context) error {

		log.Printf("Example app: Logging out")

		// delete all cookies
		for _, cookie := range c.HttpRequest().Cookies() {
			cookie.MaxAge = -1
			cookie.Value = ""
			cookie.Path = "/"
			http.SetCookie(c.HttpResponseWriter(), cookie)
		}

		return goweb.Respond.WithRedirect(c, "/")

	})

	goweb.Map("GET", "/deauth", func(c context.Context) error {

		log.Printf("Example app: Forgetting user (deleting their auth token in the AuthStore)")

		sessionCookie, sessionCookieErr := c.HttpRequest().Cookie(CookieNameSession)

		// do they have a session ID?
		if sessionCookie == nil || sessionCookieErr != nil {
			// no - they will need to login
			return RedirectToLoginPage(c)
		}

		segs := strings.Split(sessionCookie.Value, ":")
		sessionId := segs[1]

		authManager.AuthStore().DeleteAuth(sessionId)

		// send them home
		return goweb.Respond.WithRedirect(c, "/")

	})

	// GET /login
	//
	// Presents the user with a list of providers they can use to login.
	goweb.Map("GET", "/login", func(c context.Context) error {

		// create them a session ID
		sessionId := gomniauth.CreateSessionID()

		// get the target URL (URL to redirect to after they've logged in)
		targetUrl := c.QueryValue("target")

		// get the authSession
		authSession := authManager.NewSession(sessionId, nil)

		c.HttpResponseWriter().Write([]byte(`

					<title>Login</title>
					<link rel="stylesheet" href="/assets/authbuttons/auth-buttons.css">

Login

Select your method of login:

		`))

		for providerName, provider := range authManager.Providers() {

			// TODO: Make StateWith(id, target) or similar
			authUrl, _ := authSession.GetAuthURL(provider, objects.NewMap("id", sessionId, "targetUrl", targetUrl))

			c.HttpResponseWriter().Write([]byte(`

			`))
			c.HttpResponseWriter().Write([]byte(fmt.Sprintf("Sign in with %s", providerName, authUrl, provider.Name())))
			c.HttpResponseWriter().Write([]byte(`

			`))
		}

		c.HttpResponseWriter().Write([]byte(`

		`))

		return nil

	})

	// GET /auth/oauth2/{provider}/callback
	goweb.Map("/auth/{provider}/callback", func(c context.Context) error {

		provider, providerOk := authManager.Providers()[c.PathValue("provider")]

		if !providerOk {
			return errors.New("Unsupported provider")
		}

		state, stateErr := gomniauth.StateFromRequest(provider.AuthType(), c.HttpRequest())

		if stateErr != nil {
			return stateErr
		}

		returnedSessionId, sessionErr := gomniauth.IDFromState(provider.AuthType(), state)

		if sessionErr != nil {
			return sessionErr
		}

		// get the authSession
		authSession := authManager.NewSession(returnedSessionId, provider)
		callbackErr := authSession.HandleCallback(c.HttpRequest())

		if callbackErr != nil {

			// save their session ID in the cookie
			cookie := &http.Cookie{Name: CookieNameSession,
				Value: fmt.Sprintf("%s:%s", provider.Name(), returnedSessionId),
				Path:  "/",
			}
			http.SetCookie(c.HttpResponseWriter(), cookie)

			log.Printf("Example app: User has been logged in with session ID: %s", returnedSessionId)
			log.Printf("  Set cookie: %s", cookie)

			targetUrl := gomniauth.TargetURLFromState(provider.AuthType(), state)

			if len(targetUrl) == 0 {
				targetUrl = "/"
			}

			goweb.Respond.WithRedirect(c, targetUrl)

		}

		return nil
	})

	// expose the assets too
	goweb.MapStatic("assets", "assets")

	/*

	   START OF WEB SERVER CODE

	*/

	log.Print("Goweb 2")
	log.Print("by Mat Ryer and Tyler Bunnell")
	log.Print(" ")
	log.Print("Starting Goweb powered server...")

	// make a http server using the goweb.DefaultHttpHandler()
	s := &http.Server{
		Addr:           Address,
		Handler:        goweb.DefaultHttpHandler(),
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	listener, listenErr := net.Listen("tcp", Address)

	log.Printf("  visit: %s", Address)

	if listenErr != nil {
		log.Fatalf("Could not listen: %s", listenErr)
	}

	log.Println("")
	log.Println("Try some of these routes:")
	log.Printf("%s", goweb.DefaultHttpHandler())
	log.Println("\n\n")

	go func() {
		for _ = range c {

			// sig is a ^C, handle it

			// stop the HTTP server
			log.Print("Stopping the server...")
			listener.Close()

			/*
			   Tidy up and tear down
			*/
			log.Print("Tearing down...")

			// TODO: tidy code up here

			log.Fatal("Finished - bye bye.  ;-)")

		}
	}()

	// begin the server
	log.Fatalf("Error in Serve: %s", s.Serve(listener))

	/*

	   END OF WEB SERVER CODE

	*/

}

// ExampleAuthStore is an AuthStore that just keeps the Auth objects
// in memory.
type ExampleAuthStore struct {
	auths map[string]*common.Auth
}

func (s *ExampleAuthStore) GetAuth(id string) (*common.Auth, error) {
	log.Printf("ExampleAuthStore: GetAuth %s", id)
	log.Printf("  returning: %v", s.auths[id])
	return s.auths[id], nil
}
func (s *ExampleAuthStore) PutAuth(id string, auth *common.Auth) error {
	log.Printf("ExampleAuthStore: PutAuth %s", id)
	log.Printf("  putting: %v", auth)
	s.auths[id] = auth
	return nil
}
func (s *ExampleAuthStore) DeleteAuth(id string) error {
	log.Printf("ExampleAuthStore: DeleteAuth: %s", id)
	delete(s.auths, id)
	return nil
}
<commit_msg>Github user info display working<commit_after>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/stretchr/gomniauth"
	"github.com/stretchr/gomniauth/common"
	"github.com/stretchr/gomniauth/providers"
	"github.com/stretchr/goweb"
	"github.com/stretchr/goweb/context"
	"github.com/stretchr/stew/objects"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"time"
)

/*

  This is a full web-stack example showing how to use gomniauth.

	To run this app, just do:

	    clear; go build main.go; sudo ./main; rf main;

	NOTE: The domain is set to www.localhost.com, so you should route this
	      properly by editing your /etc/hosts file.

	Credit:

		The auth buttons were made by this guy:

			http://nicolasgallagher.com/lab/css3-social-signin-buttons/

*/

var Address string = ":80"

const (
	CookieNameSession string = "session"
)

// RedirectToLoginPage responds WithRedirect to the login page,
// passing the current page as the 'target' parameter.
var RedirectToLoginPage = func(c context.Context) error {
	redirectUrl := "login?target=" + c.HttpRequest().URL.Path
	log.Println("Example app: Redirecting to login page: %s", redirectUrl)
	return goweb.Respond.WithRedirect(c, redirectUrl)
}

func main() {

	/*
		Step 1. Create an AuthStore

			- An AuthStore is responsible for caching your auth tokens so you
			  don't have to send the user off to reauthenticate every time you
			  want to access their remote data.

	*/
	authStore := &ExampleAuthStore{make(map[string]*common.Auth)}

	/*
		Step 2. Create and configure an AuthManager

		  - Give it the authStore you created earlier
		  - Give it all the providers you wish to support, remember you'll
		    have to configure each provider for your application by specifying
		    Client ID, secrets, callback URLs and scopes etc. depending on the
		    auth type.

	*/
	authManager := gomniauth.NewManager(authStore,
		providers.Google("id", "secret", "http://www.localhost.com/auth/google/callback"),
		providers.Github("3d1e6ba69036e0624b61", "7e8938928d802e7582908a5eadaaaf22d64babf1", "http://www.localhost.com/auth/github/callback", "user"))

	// TODO: make the callback dynamic

	goweb.Map("GET", "/", func(c context.Context) error {

		return goweb.Respond.With(c, http.StatusOK, []byte(`

					<title>Welcome</title>

Omniauth Example Web app

							To get started, just try accessing this protected resource.

		`))

	})

	// GET /protected
	//
	// Attempts to get a protected resource.
	goweb.Map("GET", "/protected", func(c context.Context) error {

		log.Print("Example app: User tried to access protected resource")

		sessionCookie, sessionCookieErr := c.HttpRequest().Cookie(CookieNameSession)

		log.Printf("Example app: Cookies: %s", c.HttpRequest().Cookies())

		// do they have a session ID?
		if sessionCookie == nil || sessionCookieErr != nil {
			// no - they will need to login
			return RedirectToLoginPage(c)
		}

		segs := strings.Split(sessionCookie.Value, ":")
		providerName := segs[0]
		sessionId := segs[1]

		session := authManager.NewSession(sessionId, authManager.Provider(providerName))
		if authed, _ := session.IsAuthenticated(); !authed {
			// no - they will need to login
			return RedirectToLoginPage(c)
		}

		output := `

					<title>Welcome</title>

Protected Resource

						You have successfully accessed the protected resource.

						Here's a bit about you:

								Key
								Value

							$$$

							Now you can log out

							Or you can expire the internal auth token

		`

		client, err := session.AuthenticatedClient()

		if err != nil {
			//TODO: make this not bad
			return goweb.Respond.WithStatus(c, http.StatusInternalServerError)
		}

		url := ""

		switch session.Provider().Name() {
		case "Github":
			url = "https://api.github.com/user"

		case "Google":
		}

		resp, err := client.Get(url)
		if err != nil {
			//TODO: make this not bad
			return goweb.Respond.WithStatus(c, http.StatusInternalServerError)
		}
		defer resp.Body.Close()

		body, _ := ioutil.ReadAll(resp.Body)

		var userData map[string]interface{}
		json.Unmarshal(body, &userData)

		replacement := ""
		for k, v := range userData {
			replacement += fmt.Sprintf("
%s	%v
", k, v)
		}

		output = strings.Replace(output, "$$$", replacement, 1)

		return goweb.Respond.With(c, http.StatusOK, []byte(output))
	})

	goweb.Map("GET", "/logout", func(c context.Context) error {

		log.Printf("Example app: Logging out")

		// delete all cookies
		for _, cookie := range c.HttpRequest().Cookies() {
			cookie.MaxAge = -1
			cookie.Value = ""
			cookie.Path = "/"
			http.SetCookie(c.HttpResponseWriter(), cookie)
		}

		return goweb.Respond.WithRedirect(c, "/")

	})

	goweb.Map("GET", "/deauth", func(c context.Context) error {

		log.Printf("Example app: Forgetting user (deleting their auth token in the AuthStore)")

		sessionCookie, sessionCookieErr := c.HttpRequest().Cookie(CookieNameSession)

		// do they have a session ID?
		if sessionCookie == nil || sessionCookieErr != nil {
			// no - they will need to login
			return RedirectToLoginPage(c)
		}

		segs := strings.Split(sessionCookie.Value, ":")
		sessionId := segs[1]

		authManager.AuthStore().DeleteAuth(sessionId)

		// send them home
		return goweb.Respond.WithRedirect(c, "/")

	})

	// GET /login
	//
	// Presents the user with a list of providers they can use to login.
	goweb.Map("GET", "/login", func(c context.Context) error {

		// create them a session ID
		sessionId := gomniauth.CreateSessionID()

		// get the target URL (URL to redirect to after they've logged in)
		targetUrl := c.QueryValue("target")

		// get the authSession
		authSession := authManager.NewSession(sessionId, nil)

		c.HttpResponseWriter().Write([]byte(`

					<title>Login</title>
					<link rel="stylesheet" href="/assets/authbuttons/auth-buttons.css">

Login

Select your method of login:

		`))

		for providerName, provider := range authManager.Providers() {

			// TODO: Make StateWith(id, target) or similar
			authUrl, _ := authSession.GetAuthURL(provider, objects.NewMap("id", sessionId, "targetUrl", targetUrl))

			c.HttpResponseWriter().Write([]byte(`

			`))
			c.HttpResponseWriter().Write([]byte(fmt.Sprintf("Sign in with %s", providerName, authUrl, provider.Name())))
			c.HttpResponseWriter().Write([]byte(`

			`))
		}

		c.HttpResponseWriter().Write([]byte(`

		`))

		return nil

	})

	// GET /auth/oauth2/{provider}/callback
	goweb.Map("/auth/{provider}/callback", func(c context.Context) error {

		provider, providerOk := authManager.Providers()[c.PathValue("provider")]

		if !providerOk {
			return errors.New("Unsupported provider")
		}

		state, stateErr := gomniauth.StateFromRequest(provider.AuthType(), c.HttpRequest())

		if stateErr != nil {
			return stateErr
		}

		returnedSessionId, sessionErr := gomniauth.IDFromState(provider.AuthType(), state)

		if sessionErr != nil {
			return sessionErr
		}

		// get the authSession
		authSession := authManager.NewSession(returnedSessionId, provider)
		callbackErr := authSession.HandleCallback(c.HttpRequest())

		if callbackErr != nil {

			// save their session ID in the cookie
			cookie := &http.Cookie{Name: CookieNameSession,
				Value: fmt.Sprintf("%s:%s", provider.Name(), returnedSessionId),
				Path:  "/",
			}
			http.SetCookie(c.HttpResponseWriter(), cookie)

			log.Printf("Example app: User has been logged in with session ID: %s", returnedSessionId)
			log.Printf("  Set cookie: %s", cookie)

			targetUrl := gomniauth.TargetURLFromState(provider.AuthType(), state)

			if len(targetUrl) == 0 {
				targetUrl = "/"
			}

			goweb.Respond.WithRedirect(c, targetUrl)

		}

		return nil
	})

	// expose the assets too
	goweb.MapStatic("assets", "assets")

	/*

	   START OF WEB SERVER CODE

	*/

	log.Print("Goweb 2")
	log.Print("by Mat Ryer and Tyler Bunnell")
	log.Print(" ")
	log.Print("Starting Goweb powered server...")

	// make a http server using the goweb.DefaultHttpHandler()
	s := &http.Server{
		Addr:           Address,
		Handler:        goweb.DefaultHttpHandler(),
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	listener, listenErr := net.Listen("tcp", Address)

	log.Printf("  visit: %s", Address)

	if listenErr != nil {
		log.Fatalf("Could not listen: %s", listenErr)
	}

	log.Println("")
	log.Println("Try some of these routes:")
	log.Printf("%s", goweb.DefaultHttpHandler())
	log.Println("\n\n")

	go func() {
		for _ = range c {

			// sig is a ^C, handle it

			// stop the HTTP server
			log.Print("Stopping the server...")
			listener.Close()

			/*
			   Tidy up and tear down
			*/
			log.Print("Tearing down...")

			// TODO: tidy code up here

			log.Fatal("Finished - bye bye.  ;-)")

		}
	}()

	// begin the server
	log.Fatalf("Error in Serve: %s", s.Serve(listener))

	/*

	   END OF WEB SERVER CODE

	*/

}

// ExampleAuthStore is an AuthStore that just keeps the Auth objects
// in memory.
type ExampleAuthStore struct {
	auths map[string]*common.Auth
}

func (s *ExampleAuthStore) GetAuth(id string) (*common.Auth, error) {
	log.Printf("ExampleAuthStore: GetAuth %s", id)
	log.Printf("  returning: %v", s.auths[id])
	return s.auths[id], nil
}
func (s *ExampleAuthStore) PutAuth(id string, auth *common.Auth) error {
	log.Printf("ExampleAuthStore: PutAuth %s", id)
	log.Printf("  putting: %v", auth)
	s.auths[id] = auth
	return nil
}
func (s *ExampleAuthStore) DeleteAuth(id string) error {
	log.Printf("ExampleAuthStore: DeleteAuth: %s", id)
	delete(s.auths, id)
	return nil
}
<|endoftext|>


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

package docker_test

import (
	"archive/tar"
	"bytes"
	"io"
	"log"
	"time"

	"github.com/fsouza/go-dockerclient"
)

func ExampleClient_AttachToContainer() {
	client, err := docker.NewClient("http://localhost:4243")
	if err != nil {
		log.Fatal(err)
	}
	client.SkipServerVersionCheck = true
	// Reading logs from container a84849 and sending them to buf.
	var buf bytes.Buffer
	err = client.AttachToContainer(docker.AttachToContainerOptions{
		Container:    "a84849",
		OutputStream: &buf,
		Logs:         true,
		Stdout:       true,
		Stderr:       true,
	})
	if err != nil {
		log.Fatal(err)
	}
	log.Println(buf.String())
	// Attaching to stdout and streaming.
	buf.Reset()
	err = client.AttachToContainer(docker.AttachToContainerOptions{
		Container:    "a84849",
		OutputStream: &buf,
		Stdout:       true,
		Stream:       true,
	})
	if err != nil {
		log.Fatal(err)
	}
	log.Println(buf.String())
}

func ExampleClient_CopyFromContainer() {
	client, err := docker.NewClient("http://localhost:4243")
	if err != nil {
		log.Fatal(err)
	}
	cid := "a84849"
	// Copy resulting file
	var buf bytes.Buffer
	filename := "/tmp/output.txt"
	err = client.CopyFromContainer(docker.CopyFromContainerOptions{
		Container:    cid,
		Resource:     filename,
		OutputStream: &buf,
	})
	if err != nil {
		log.Fatalf("Error while copying from %s: %s\n", cid, err)
	}
	content := new(bytes.Buffer)
	r := bytes.NewReader(buf.Bytes())
	tr := tar.NewReader(r)
	tr.Next()
	if err != nil && err != io.EOF {
		log.Fatal(err)
	}
	if _, err := io.Copy(content, tr); err != nil {
		log.Fatal(err)
	}
	log.Println(buf.String())
}

func ExampleClient_BuildImage() {
	client, err := docker.NewClient("http://localhost:4243")
	if err != nil {
		log.Fatal(err)
	}

	t := time.Now()
	inputbuf, outputbuf := bytes.NewBuffer(nil), bytes.NewBuffer(nil)
	tr := tar.NewWriter(inputbuf)
	tr.WriteHeader(&tar.Header{Name: "Dockerfile", Size: 10, ModTime: t, AccessTime: t, ChangeTime: t})
	tr.Write([]byte("FROM base\n"))
	tr.Close()
	opts := docker.BuildImageOptions{
		Name:         "test",
		InputStream:  inputbuf,
		OutputStream: outputbuf,
	}
	if err := client.BuildImage(opts); err != nil {
		log.Fatal(err)
	}
}

func ExampleClient_ListenEvents() {
	client, err := docker.NewClient("http://localhost:4243")
	if err != nil {
		log.Fatal(err)
	}

	listener := make(chan *docker.APIEvents)
	err = client.AddEventListener(listener)
	if err != nil {
		log.Fatal(err)
	}

	defer func() {

		err = client.RemoveEventListener(listener)
		if err != nil {
			log.Fatal(err)
		}

	}()

	timeout := time.After(1 * time.Second)

	for {
		select {
		case msg := <-listener:
			log.Println(msg)
		case <-timeout:
			break
		}
	}

}
<commit_msg>example: add some Env examples<commit_after>// Copyright 2014 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package docker_test

import (
	"archive/tar"
	"bytes"
	"fmt"
	"github.com/fsouza/go-dockerclient"
	"io"
	"log"
	"time"
)

func ExampleClient_AttachToContainer() {
	client, err := docker.NewClient("http://localhost:4243")
	if err != nil {
		log.Fatal(err)
	}
	client.SkipServerVersionCheck = true
	// Reading logs from container a84849 and sending them to buf.
	var buf bytes.Buffer
	err = client.AttachToContainer(docker.AttachToContainerOptions{
		Container:    "a84849",
		OutputStream: &buf,
		Logs:         true,
		Stdout:       true,
		Stderr:       true,
	})
	if err != nil {
		log.Fatal(err)
	}
	log.Println(buf.String())
	buf.Reset()
	err = client.AttachToContainer(docker.AttachToContainerOptions{
		Container:    "a84849",
		OutputStream: &buf,
		Stdout:       true,
		Stream:       true,
	})
	if err != nil {
		log.Fatal(err)
	}
	log.Println(buf.String())
}

func ExampleClient_CopyFromContainer() {
	client, err := docker.NewClient("http://localhost:4243")
	if err != nil {
		log.Fatal(err)
	}
	cid := "a84849"
	var buf bytes.Buffer
	filename := "/tmp/output.txt"
	err = client.CopyFromContainer(docker.CopyFromContainerOptions{
		Container:    cid,
		Resource:     filename,
		OutputStream: &buf,
	})
	if err != nil {
		log.Fatalf("Error while copying from %s: %s\n", cid, err)
	}
	content := new(bytes.Buffer)
	r := bytes.NewReader(buf.Bytes())
	tr := tar.NewReader(r)
	tr.Next()
	if err != nil && err != io.EOF {
		log.Fatal(err)
	}
	if _, err := io.Copy(content, tr); err != nil {
		log.Fatal(err)
	}
	log.Println(buf.String())
}

func ExampleClient_BuildImage() {
	client, err := docker.NewClient("http://localhost:4243")
	if err != nil {
		log.Fatal(err)
	}

	t := time.Now()
	inputbuf, outputbuf := bytes.NewBuffer(nil), bytes.NewBuffer(nil)
	tr := tar.NewWriter(inputbuf)
	tr.WriteHeader(&tar.Header{Name: "Dockerfile", Size: 10, ModTime: t, AccessTime: t, ChangeTime: t})
	tr.Write([]byte("FROM base\n"))
	tr.Close()
	opts := docker.BuildImageOptions{
		Name:         "test",
		InputStream:  inputbuf,
		OutputStream: outputbuf,
	}
	if err := client.BuildImage(opts); err != nil {
		log.Fatal(err)
	}
}

func ExampleClient_ListenEvents() {
	client, err := docker.NewClient("http://localhost:4243")
	if err != nil {
		log.Fatal(err)
	}

	listener := make(chan *docker.APIEvents)
	err = client.AddEventListener(listener)
	if err != nil {
		log.Fatal(err)
	}

	defer func() {

		err = client.RemoveEventListener(listener)
		if err != nil {
			log.Fatal(err)
		}

	}()

	timeout := time.After(1 * time.Second)

	for {
		select {
		case msg := <-listener:
			log.Println(msg)
		case <-timeout:
			break
		}
	}

}

func ExampleEnv_Map() {
	e := docker.Env([]string{"A=1", "B=2", "C=3"})
	envs := e.Map()
	for k, v := range envs {
		fmt.Printf("%s=%q\n", k, v)
	}
}

func ExampleEnv_SetJSON() {
	type Person struct {
		Name string
		Age  int
	}
	p := Person{Name: "Gopher", Age: 4}
	var e docker.Env
	err := e.SetJSON("person", p)
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleEnv_GetJSON() {
	type Person struct {
		Name string
		Age  int
	}
	p := Person{Name: "Gopher", Age: 4}
	var e docker.Env
	e.Set("person", `{"name":"Gopher","age":4}`)
	err := e.GetJSON("person", &p)
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package wstest_test

import (
	"fmt"
	"net/http"

	"github.com/gorilla/websocket"
	"github.com/posener/wstest"
)

func ExampleNewClient() {
	var (
		// simple echo dialer
		s = &echoServer{}

		// create a dialer to the dialer
		// this send an HTTP request to the http.Handler, and wait for the connection
		// upgrade response.
		// it uses the gorilla's websocket.Dial function, over a fake net.Conn struct.
		// it runs the handler's ServeHTTP function in a goroutine, so the handler can
		// communicate with a client running on the current program flow
		d = wstest.NewDialer(s, nil)

		resp string
	)

	c, _, err := d.Dial("ws://example.org/ws", nil)
	if err != nil {
		panic(err)
	}

	// the client is also a websocket.Conn object, so all websocket functions
	// can be used with it. here we write a JSON string to the connection.
	c.WriteJSON("hello echo server")

	// Reading from the socket is done with the websocket.Conn functions as well.
	c.ReadJSON(&resp)
	fmt.Println(resp)

	// Pass another message in the connection
	c.WriteJSON("byebye")
	c.ReadJSON(&resp)
	fmt.Println(resp)

	// Finally close the connection
	err = c.Close()
	if err != nil {
		panic(err)
	}

	<-s.Done

	// Output: hello echo server!
	// byebye!
}

type echoServer struct {
	upgrader websocket.Upgrader
	Done     chan struct{}
}

func (s *echoServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	var (
		err error
	)

	s.Done = make(chan struct{})
	defer close(s.Done)

	if r.URL.Path != "/ws" {
		w.WriteHeader(http.StatusNotFound)
		return
	}

	var conn *websocket.Conn
	conn, err = s.upgrader.Upgrade(w, r, nil)
	if err != nil {
		return
	}

	for {
		var msg string
		err := conn.ReadJSON(&msg)
		if err != nil {
			return
		}
		conn.WriteJSON(msg + "!")
	}
}
<commit_msg>Fix example name<commit_after>package wstest_test

import (
	"fmt"
	"net/http"

	"github.com/gorilla/websocket"
	"github.com/posener/wstest"
)

func ExampleNewDialer() {
	var (
		// simple echo dialer
		s = &echoServer{}

		// create a dialer to the dialer
		// this send an HTTP request to the http.Handler, and wait for the connection
		// upgrade response.
		// it uses the gorilla's websocket.Dial function, over a fake net.Conn struct.
		// it runs the handler's ServeHTTP function in a goroutine, so the handler can
		// communicate with a client running on the current program flow
		d = wstest.NewDialer(s, nil)

		resp string
	)

	c, _, err := d.Dial("ws://example.org/ws", nil)
	if err != nil {
		panic(err)
	}

	// the client is also a websocket.Conn object, so all websocket functions
	// can be used with it. here we write a JSON string to the connection.
	c.WriteJSON("hello echo server")

	// Reading from the socket is done with the websocket.Conn functions as well.
	c.ReadJSON(&resp)
	fmt.Println(resp)

	// Pass another message in the connection
	c.WriteJSON("byebye")
	c.ReadJSON(&resp)
	fmt.Println(resp)

	// Finally close the connection
	err = c.Close()
	if err != nil {
		panic(err)
	}

	<-s.Done

	// Output: hello echo server!
	// byebye!
}

type echoServer struct {
	upgrader websocket.Upgrader
	Done     chan struct{}
}

func (s *echoServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	var (
		err error
	)

	s.Done = make(chan struct{})
	defer close(s.Done)

	if r.URL.Path != "/ws" {
		w.WriteHeader(http.StatusNotFound)
		return
	}

	var conn *websocket.Conn
	conn, err = s.upgrader.Upgrade(w, r, nil)
	if err != nil {
		return
	}

	for {
		var msg string
		err := conn.ReadJSON(&msg)
		if err != nil {
			return
		}
		conn.WriteJSON(msg + "!")
	}
}
<|endoftext|>