<commit_before>package gtk

// #include <gtk/gtkx.h>
// #include <gtk/gtksocket.h>
// #include <gtk/gtkplug.h>
// #include <gdk/gdkdisplay.h>
// #include "socket_plug.go.h"
import "C"
import (
	"github.com/gotk3/gotk3/gdk"
	"github.com/gotk3/gotk3/glib"
	"unsafe"
)

func init() {
	tm := []glib.TypeMarshaler{
		{glib.Type(C.gtk_socket_get_type()), marshalSocket},
		{glib.Type(C.gtk_plug_get_type()), marshalPlug},
	}

	glib.RegisterGValueMarshalers(tm)

	WrapMap["GtkSocket"] = wrapSocket
	WrapMap["GtkPlug"] = wrapPlug
}

/*
 * GtkSocket
 */

// Socket is a representation of GTK's GtkSocket
type Socket struct {
	Container
}

// native returns a pointer to the underlying GtkSocket
func (v *Socket) native() *C.GtkSocket {
	if v == nil || v.GObject == nil {
		return nil
	}
	p := unsafe.Pointer(v.GObject)
	return C.toGtkSocket(p)
}

func marshalSocket(p uintptr) (interface{}, error) {
	c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
	obj := glib.Take(unsafe.Pointer(c))
	return wrapSocket(obj), nil
}

func wrapSocket(obj *glib.Object) *Socket {
	return &Socket{Container{Widget{glib.InitiallyUnowned{obj}}}}
}

// SocketNew is a wrapper around gtk_socket_new().
// Create a new empty GtkSocket.
func SocketNew() (*Socket, error) {
	c := C.gtk_socket_new()
	if c == nil {
		return nil, nilPtrErr
	}
	return wrapSocket(glib.Take(unsafe.Pointer(c))), nil
}

// AddId is a wrapper around gtk_socket_add_id().
// Adds an XEMBED client, such as a GtkPlug, to the GtkSocket. The client may be in the same process or in a different
// process.
// To embed a GtkPlug in a GtkSocket, you can either create the GtkPlug with gtk_plug_new (0), call gtk_plug_get_id()
// to get the window ID of the plug, and then pass that to the gtk_socket_add_id(), or you can call gtk_socket_get_id()
// to get the window ID for the socket, and call gtk_plug_new() passing in that ID.
// The GtkSocket must have already be added into a toplevel window before you can make this call.
func (v *Socket) AddId(window uint) {
	C.gtk_socket_add_id(v.native(), C.ulong(window))
}

// GetId is a wrapper around gtk_socket_get_id().
// Gets the window ID of a GtkSocket widget, which can then be used to create a client embedded inside the socket,
// for instance with gtk_plug_new().
// The GtkSocket must have already be added into a toplevel window before you can make this call.
func (v *Socket) GetId() uint {
	c := C.gtk_socket_get_id(v.native())
	return uint(c)
}

// GetPlugWindow is a wrapper around gtk_socket_get_plug_window().
// Retrieves the window of the plug. Use this to check if the plug has been created inside of the socket.
func (v *Socket) GetPlugWindow() (*Window, error) {
	c := C.gtk_socket_get_plug_window(v.native())
	if c == nil {
		return nil, nilPtrErr
	}
	return wrapWindow(glib.Take(unsafe.Pointer(c))), nil
}

/*
 * GtkSocket
 */

// Plug is a representation of GTK's GtkPlug
type Plug struct {
	Window
}

// native returns a pointer to the underlying GtkSocket
func (v *Plug) native() *C.GtkPlug {
	if v == nil || v.GObject == nil {
		return nil
	}
	p := unsafe.Pointer(v.GObject)
	return C.toGtkPlug(p)
}

// native returns a C pointer to the underlying GdkDisplay.
func native(v *gdk.Display) *C.GdkDisplay {
	// I'd love to not have to copy native() from gdk/gdk.go, but it appears you can't just
	// pass C structs from package to package
	if v == nil || v.GObject == nil {
		return nil
	}
	p := unsafe.Pointer(v.GObject)
	return C.toGdkDisplay(p)
}

func marshalPlug(p uintptr) (interface{}, error) {
	c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
	obj := glib.Take(unsafe.Pointer(c))
	return wrapPlug(obj), nil
}

func wrapPlug(obj *glib.Object) *Plug {
	return &Plug{Window{Bin{Container{Widget{glib.InitiallyUnowned{obj}}}}}}
}

// PlugNew is a wrapper around gtk_plug_new().
// Creates a new plug widget inside the GtkSocket identified by socket_id.
// If socket_id is 0, the plug is left “unplugged” and can later be plugged into a GtkSocket by gtk_socket_add_id().
func PlugNew(socketId uint) (*Plug, error) {
	c := C.gtk_plug_new(C.ulong(socketId))
	if c == nil {
		return nil, nilPtrErr
	}
	return wrapPlug(glib.Take(unsafe.Pointer(c))), nil
}

// PlugNewForDisplay is a wrapper around gtk_plug_new_for_display().
// Creates a new plug widget inside the GtkSocket identified by socket_id.
// If socket_id is 0, the plug is left “unplugged” and can later be plugged into a GtkSocket by gtk_socket_add_id().
func PlugNewForDisplay(display *gdk.Display, socketId uint) (*Plug, error) {
	c := C.gtk_plug_new_for_display(native(display), C.ulong(socketId))
	if c == nil {
		return nil, nilPtrErr
	}
	return wrapPlug(glib.Take(unsafe.Pointer(c))), nil
}

// Construct is a wrapper around gtk_plug_construct().
// Finish the initialization of plug for a given GtkSocket identified by socket_id.
// This function will generally only be used by classes deriving from GtkPlug.
func (v *Plug) Construct(socketId uint) {
	C.gtk_plug_construct(v.native(), C.ulong(socketId))
}

// ConstructForDisplay is a wrapper around gtk_plug_construct_for_display().
// Finish the initialization of plug for a given GtkSocket identified by socket_id which is currently
// displayed on display.
// This function will generally only be used by classes deriving from GtkPlug.
func (v *Plug) ConstructForDisplay(display *gdk.Display, socketId uint) {
	C.gtk_plug_construct_for_display(v.native(), native(display), C.ulong(socketId))
}

// GetId is a wrapper around gtk_plug_get_id().
// Gets the window ID of a GtkPlug widget, which can then be used to embed this window inside another window,
// for instance with gtk_socket_add_id().
func (v *Plug) GetId() uint {
	c := C.gtk_plug_get_id(v.native())
	return uint(c)
}

// GetEmbedded is a wrapper around gtk_plug_get_embedded().
// Determines whether the plug is embedded in a socket.
func (v *Plug) GetEmbedded() bool {
	c := C.gtk_plug_get_embedded(v.native())
	return gobool(c)
}

// GetSocketWindow is a wrapper around gtk_plug_get_socket_window().
// Retrieves the socket the plug is embedded in.
func (v *Plug) GetSocketWindow() (*Window, error) {
	c := C.gtk_plug_get_socket_window(v.native())
	if c == nil {
		return nil, nilPtrErr
	}
	return wrapWindow(glib.Take(unsafe.Pointer(c))), nil
}
<commit_msg>Use C.Windows instead of C.ulong<commit_after>package gtk

// #include <gtk/gtkx.h>
// #include <gtk/gtksocket.h>
// #include <gtk/gtkplug.h>
// #include <gdk/gdkdisplay.h>
// #include "socket_plug.go.h"
import "C"
import (
	"github.com/gotk3/gotk3/gdk"
	"github.com/gotk3/gotk3/glib"
	"unsafe"
)

func init() {
	tm := []glib.TypeMarshaler{
		{glib.Type(C.gtk_socket_get_type()), marshalSocket},
		{glib.Type(C.gtk_plug_get_type()), marshalPlug},
	}

	glib.RegisterGValueMarshalers(tm)

	WrapMap["GtkSocket"] = wrapSocket
	WrapMap["GtkPlug"] = wrapPlug
}

/*
 * GtkSocket
 */

// Socket is a representation of GTK's GtkSocket
type Socket struct {
	Container
}

// native returns a pointer to the underlying GtkSocket
func (v *Socket) native() *C.GtkSocket {
	if v == nil || v.GObject == nil {
		return nil
	}
	p := unsafe.Pointer(v.GObject)
	return C.toGtkSocket(p)
}

func marshalSocket(p uintptr) (interface{}, error) {
	c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
	obj := glib.Take(unsafe.Pointer(c))
	return wrapSocket(obj), nil
}

func wrapSocket(obj *glib.Object) *Socket {
	return &Socket{Container{Widget{glib.InitiallyUnowned{obj}}}}
}

// SocketNew is a wrapper around gtk_socket_new().
// Create a new empty GtkSocket.
func SocketNew() (*Socket, error) {
	c := C.gtk_socket_new()
	if c == nil {
		return nil, nilPtrErr
	}
	return wrapSocket(glib.Take(unsafe.Pointer(c))), nil
}

// AddId is a wrapper around gtk_socket_add_id().
// Adds an XEMBED client, such as a GtkPlug, to the GtkSocket. The client may be in the same process or in a different
// process.
// To embed a GtkPlug in a GtkSocket, you can either create the GtkPlug with gtk_plug_new (0), call gtk_plug_get_id()
// to get the window ID of the plug, and then pass that to the gtk_socket_add_id(), or you can call gtk_socket_get_id()
// to get the window ID for the socket, and call gtk_plug_new() passing in that ID.
// The GtkSocket must have already be added into a toplevel window before you can make this call.
func (v *Socket) AddId(window uint) {
	C.gtk_socket_add_id(v.native(), C.Window(window))
}

// GetId is a wrapper around gtk_socket_get_id().
// Gets the window ID of a GtkSocket widget, which can then be used to create a client embedded inside the socket,
// for instance with gtk_plug_new().
// The GtkSocket must have already be added into a toplevel window before you can make this call.
func (v *Socket) GetId() uint {
	c := C.gtk_socket_get_id(v.native())
	return uint(c)
}

// GetPlugWindow is a wrapper around gtk_socket_get_plug_window().
// Retrieves the window of the plug. Use this to check if the plug has been created inside of the socket.
func (v *Socket) GetPlugWindow() (*Window, error) {
	c := C.gtk_socket_get_plug_window(v.native())
	if c == nil {
		return nil, nilPtrErr
	}
	return wrapWindow(glib.Take(unsafe.Pointer(c))), nil
}

/*
 * GtkSocket
 */

// Plug is a representation of GTK's GtkPlug
type Plug struct {
	Window
}

// native returns a pointer to the underlying GtkSocket
func (v *Plug) native() *C.GtkPlug {
	if v == nil || v.GObject == nil {
		return nil
	}
	p := unsafe.Pointer(v.GObject)
	return C.toGtkPlug(p)
}

// native returns a C pointer to the underlying GdkDisplay.
func native(v *gdk.Display) *C.GdkDisplay {
	// I'd love to not have to copy native() from gdk/gdk.go, but it appears you can't just
	// pass C structs from package to package
	if v == nil || v.GObject == nil {
		return nil
	}
	p := unsafe.Pointer(v.GObject)
	return C.toGdkDisplay(p)
}

func marshalPlug(p uintptr) (interface{}, error) {
	c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
	obj := glib.Take(unsafe.Pointer(c))
	return wrapPlug(obj), nil
}

func wrapPlug(obj *glib.Object) *Plug {
	return &Plug{Window{Bin{Container{Widget{glib.InitiallyUnowned{obj}}}}}}
}

// PlugNew is a wrapper around gtk_plug_new().
// Creates a new plug widget inside the GtkSocket identified by socket_id.
// If socket_id is 0, the plug is left “unplugged” and can later be plugged into a GtkSocket by gtk_socket_add_id().
func PlugNew(socketId uint) (*Plug, error) {
	c := C.gtk_plug_new(C.Window(socketId))
	if c == nil {
		return nil, nilPtrErr
	}
	return wrapPlug(glib.Take(unsafe.Pointer(c))), nil
}

// PlugNewForDisplay is a wrapper around gtk_plug_new_for_display().
// Creates a new plug widget inside the GtkSocket identified by socket_id.
// If socket_id is 0, the plug is left “unplugged” and can later be plugged into a GtkSocket by gtk_socket_add_id().
func PlugNewForDisplay(display *gdk.Display, socketId uint) (*Plug, error) {
	c := C.gtk_plug_new_for_display(native(display), C.Window(socketId))
	if c == nil {
		return nil, nilPtrErr
	}
	return wrapPlug(glib.Take(unsafe.Pointer(c))), nil
}

// Construct is a wrapper around gtk_plug_construct().
// Finish the initialization of plug for a given GtkSocket identified by socket_id.
// This function will generally only be used by classes deriving from GtkPlug.
func (v *Plug) Construct(socketId uint) {
	C.gtk_plug_construct(v.native(), C.Window(socketId))
}

// ConstructForDisplay is a wrapper around gtk_plug_construct_for_display().
// Finish the initialization of plug for a given GtkSocket identified by socket_id which is currently
// displayed on display.
// This function will generally only be used by classes deriving from GtkPlug.
func (v *Plug) ConstructForDisplay(display *gdk.Display, socketId uint) {
	C.gtk_plug_construct_for_display(v.native(), native(display), C.Window(socketId))
}

// GetId is a wrapper around gtk_plug_get_id().
// Gets the window ID of a GtkPlug widget, which can then be used to embed this window inside another window,
// for instance with gtk_socket_add_id().
func (v *Plug) GetId() uint {
	c := C.gtk_plug_get_id(v.native())
	return uint(c)
}

// GetEmbedded is a wrapper around gtk_plug_get_embedded().
// Determines whether the plug is embedded in a socket.
func (v *Plug) GetEmbedded() bool {
	c := C.gtk_plug_get_embedded(v.native())
	return gobool(c)
}

// GetSocketWindow is a wrapper around gtk_plug_get_socket_window().
// Retrieves the socket the plug is embedded in.
func (v *Plug) GetSocketWindow() (*Window, error) {
	c := C.gtk_plug_get_socket_window(v.native())
	if c == nil {
		return nil, nilPtrErr
	}
	return wrapWindow(glib.Take(unsafe.Pointer(c))), nil
}
<|endoftext|>


<commit_before>package zfs

import (
	"bufio"
	"bytes"
	"fmt"
	"time"
)

type (
	// SnapshotList represents a list of snapshots. These will always be sorted
	// by creation time.
	SnapshotList []*Snapshot
)

// NewSnapshotListFromDataset will create a new SnapshotList from the output of the provided ZfsExecutor
func (l SnapshotList) NewSnapshotListFromDataset(zfsExecutor Executor, dataset string) (SnapshotList, error) {
	list := SnapshotList{}
	lastCreation := time.Time{}
	output, err := zfsExecutor.GetSnapshotList(dataset)
	if err != nil {
		return nil, err
	}
	scanner := bufio.NewScanner(bytes.NewReader(output))
	for scanner.Scan() {
		s, err := NewSnapshotFromLine(scanner.Text())
		if err != nil {
			return nil, err
		}
		if lastCreation.Sub(s.Creation) > time.Second {
			return nil, fmt.Errorf("output does not appear sorted. %d < %d", s.Creation.Unix(), lastCreation.Unix())
		}
		lastCreation = s.Creation
		list = append(list, s)
	}
	return list, nil
}

// Next will retrieve a pointer to the next Snapshot in l where the snapshot
// creation time is newer than or equal to from.
func (l SnapshotList) Next(from time.Time) *Snapshot {
	for _, snapshot := range l {
		if snapshot.Creation.Sub(from) >= 0 {
			return snapshot
		}
	}
	return nil
}

// Oldest will return a pointer to the oldest snapshot in l.
func (l SnapshotList) Oldest() *Snapshot {
	if len(l) < 1 {
		return nil
	}
	return l[0]
}

// Latest will return a pointer to the latest snapshot in l.
func (l SnapshotList) Latest() *Snapshot {
	if len(l) < 1 {
		return nil
	}
	return l[len(l)-1]
}

// String imeplements Stringer.
func (l SnapshotList) String() string {
	out := "[ "

	for _, s := range l {
		out += fmt.Sprintf("%s ", s.String())
	}

	return out + "]"
}

// KeepLatest will keep the num latest snapshots.
func (l SnapshotList) KeepLatest(num int) {
	start := len(l) - num

	if start < 0 {
		start = 0
	}

	for i := start; i < len(l); i++ {
		l[i].Keep = true
	}
}

// KeepNamed will keep all snapshots named in names.
func (l SnapshotList) KeepNamed(names []string) {
	// Start by indexing names for lookups.
	index := make(map[string]bool)
	for _, name := range names {
		index[name] = true
	}

	for _, snapshot := range l {
		if index[snapshot.SnapshotName()] {
			snapshot.Keep = true
		}
	}
}

// KeepOldest keeps the num oldest snapshots.
func (l SnapshotList) KeepOldest(num int) {
	for i := 0; i < num && i < len(l); i++ {
		l[i].Keep = true
	}
}

// Sieve will mark snapshots to keep according to start time and frequency.
func (l SnapshotList) Sieve(start time.Time, frequency time.Duration) {
	// The ZFS resolution on creation time is one second. If we get a frequency
	// below one second, we have to keep everything after start.
	if frequency < time.Second {
		for _, s := range l {
			if s.Creation.Sub(start) >= 0 {
				s.Keep = true
			}
		}
		return
	}
	for s := l.Next(start); s != nil; s = l.Next(s.Creation.Add(frequency)) {
		s.Keep = true
	}
}

// ResetSieve will mark all snapshots for deletion.
func (l SnapshotList) ResetSieve() {
	for _, s := range l {
		s.Keep = false
	}
}
<commit_msg>Be more resilient to execution time.<commit_after>package zfs

import (
	"bufio"
	"bytes"
	"fmt"
	"time"
)

type (
	// SnapshotList represents a list of snapshots. These will always be sorted
	// by creation time.
	SnapshotList []*Snapshot
)

// NewSnapshotListFromDataset will create a new SnapshotList from the output of the provided ZfsExecutor
func (l SnapshotList) NewSnapshotListFromDataset(zfsExecutor Executor, dataset string) (SnapshotList, error) {
	list := SnapshotList{}
	lastCreation := time.Time{}
	output, err := zfsExecutor.GetSnapshotList(dataset)
	if err != nil {
		return nil, err
	}
	scanner := bufio.NewScanner(bytes.NewReader(output))
	for scanner.Scan() {
		s, err := NewSnapshotFromLine(scanner.Text())
		if err != nil {
			return nil, err
		}
		if lastCreation.Sub(s.Creation) > time.Second {
			return nil, fmt.Errorf("output does not appear sorted. %d < %d", s.Creation.Unix(), lastCreation.Unix())
		}
		lastCreation = s.Creation
		list = append(list, s)
	}
	return list, nil
}

// Next will retrieve a pointer to the next Snapshot in l where the snapshot
// creation time is newer than or equal to from.
func (l SnapshotList) Next(from time.Time) *Snapshot {
	for _, snapshot := range l {
		if snapshot.Creation.Sub(from) >= 0 {
			return snapshot
		}
	}
	return nil
}

// Oldest will return a pointer to the oldest snapshot in l.
func (l SnapshotList) Oldest() *Snapshot {
	if len(l) < 1 {
		return nil
	}
	return l[0]
}

// Latest will return a pointer to the latest snapshot in l.
func (l SnapshotList) Latest() *Snapshot {
	if len(l) < 1 {
		return nil
	}
	return l[len(l)-1]
}

// String imeplements Stringer.
func (l SnapshotList) String() string {
	out := "[ "

	for _, s := range l {
		out += fmt.Sprintf("%s ", s.String())
	}

	return out + "]"
}

// KeepLatest will keep the num latest snapshots.
func (l SnapshotList) KeepLatest(num int) {
	start := len(l) - num

	if start < 0 {
		start = 0
	}

	for i := start; i < len(l); i++ {
		l[i].Keep = true
	}
}

// KeepNamed will keep all snapshots named in names.
func (l SnapshotList) KeepNamed(names []string) {
	// Start by indexing names for lookups.
	index := make(map[string]bool)
	for _, name := range names {
		index[name] = true
	}

	for _, snapshot := range l {
		if index[snapshot.SnapshotName()] {
			snapshot.Keep = true
		}
	}
}

// KeepOldest keeps the num oldest snapshots.
func (l SnapshotList) KeepOldest(num int) {
	for i := 0; i < num && i < len(l); i++ {
		l[i].Keep = true
	}
}

// Sieve will mark snapshots to keep according to start time and frequency.
func (l SnapshotList) Sieve(start time.Time, frequency time.Duration) {
	// The ZFS resolution on creation time is one second. If we get a frequency
	// below one second, we have to keep everything after start.
	if frequency < time.Second {
		for _, s := range l {
			if s.Creation.Sub(start) >= 0 {
				s.Keep = true
			}
		}
		return
	}

	// We move start back to a point in time where it will "snap" to a
	// frequency based on some predefined reference time in the past.
	// We do this to make zfs-cleaner more resilient to the execution start
	// time of zfs-cleaner itself.
	// Imagine we have two ZFS servers synchronizing snapshots. If they both
	// run zfs-cleaner, they could easily diverge on what snapshots to keep,
	// and which to delete based on execution time.
	// This trick should make sure that we're consistent about what to
	// delete and what to destroy since ZFS snapshots maintain the creation-
	// time across pools.
	// Please note that zfs-cleaner run should happen at roughly the same
	// time on all hosts. As long as zfs-cleaners runs more often than the
	// keep frequency, the result should be predictable.
	// If you have a planline like "keep 2h for 24h", you should execute
	// zfs-cleaner every hour to ensure consistency, but it's not important
	// *when* zfs-cleaner executes, as long as it's in a shorter span than
	// the keep frequency.
	// The reference time is the standard UNIX epoch at midnight January
	// 1st 1970, but that's not important, as long it's guaranteed to be
	// in the past.

	// Calculate how much to move the start back in time to snap to a time
	// aligned to the frequency.
	offset := time.Duration(start.UnixNano()) % frequency

	// Do the actual move. If start was already snapped (by chance) when
	// passed, this does nothing since offset will be zero.
	start = start.Add(-offset)

	for s := l.Next(start); s != nil; s = l.Next(s.Creation.Add(frequency)) {
		s.Keep = true
	}
}

// ResetSieve will mark all snapshots for deletion.
func (l SnapshotList) ResetSieve() {
	for _, s := range l {
		s.Keep = false
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"fmt"
	"strings"
	"runtime"
    "text/tabwriter"
    "./cli"
)

func printVersion(ctx cli.Context) {
    fmt.Printf("%s v%s, %s\n", Name, Version, runtime.Version())
}

func printHelp(ctx cli.Context) {
    w := new(tabwriter.Writer)
    w.Init(os.Stdout, 0, 0, 3, ' ', 0)

    fmt.Fprintf(w, "%s usage:\n\n", Name)

    for _, h := range ctx.Handlers() {
        fmt.Fprintf(w, "%s %s\t%s\n", Name, h.Pattern, h.Description)
    }

    w.Flush()
}

func printCommandHelp(ctx cli.Context) {
    args := ctx.Args()
    printCommandPrefixHelp(ctx, args.String("command"))
}

func printSubCommandHelp(ctx cli.Context) {
    args := ctx.Args()
    printCommandPrefixHelp(ctx, args.String("command"), args.String("subcommand"))
}

func printCommandPrefixHelp(ctx cli.Context, prefix ...string) {
    handler := getHandler(ctx.Handlers(), prefix)

    if handler == nil {
        ExitF("Command not found")
    }

    w := new(tabwriter.Writer)
    w.Init(os.Stdout, 0, 0, 3, ' ', 0)

    fmt.Fprintf(w, "%s\n", handler.Description)
    fmt.Fprintf(w, "%s %s\n", Name, handler.Pattern)
    for _, group := range handler.FlagGroups {
        fmt.Fprintf(w, "\n%s:\n", group.Name)
        for _, flag := range group.Flags {
            boolFlag, isBool := flag.(cli.BoolFlag)
            if isBool && boolFlag.OmitValue {
                fmt.Fprintf(w, "  %s\t%s\n", strings.Join(flag.GetPatterns(), ", "), flag.GetDescription())
            } else {
                fmt.Fprintf(w, "  %s <%s>\t%s\n", strings.Join(flag.GetPatterns(), ", "), flag.GetName(), flag.GetDescription())
            }
        }
    }

    w.Flush()
}

func getHandler(handlers []*cli.Handler, prefix []string) *cli.Handler {
    for _, h := range handlers {
        pattern := stripOptionals(h.SplitPattern())

        if len(prefix) > len(pattern) {
            continue
        }

        if equal(prefix, pattern[:len(prefix)]) {
            return h
        }
    }

    return nil
}

// Strip optional groups (<...>) from pattern
func stripOptionals(pattern []string) []string {
    newArgs := []string{}

    for _, arg := range pattern {
        if strings.HasPrefix(arg, "[") && strings.HasSuffix(arg, "]") {
            continue
        }
        newArgs = append(newArgs, arg)
    }
    return newArgs
}
<commit_msg>Add os/arch to version<commit_after>package main

import (
	"os"
	"fmt"
	"strings"
	"runtime"
    "text/tabwriter"
    "./cli"
)

func printVersion(ctx cli.Context) {
    fmt.Printf("%s: %s\n", Name, Version)
    fmt.Printf("Golang: %s\n", runtime.Version())
    fmt.Printf("OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
}

func printHelp(ctx cli.Context) {
    w := new(tabwriter.Writer)
    w.Init(os.Stdout, 0, 0, 3, ' ', 0)

    fmt.Fprintf(w, "%s usage:\n\n", Name)

    for _, h := range ctx.Handlers() {
        fmt.Fprintf(w, "%s %s\t%s\n", Name, h.Pattern, h.Description)
    }

    w.Flush()
}

func printCommandHelp(ctx cli.Context) {
    args := ctx.Args()
    printCommandPrefixHelp(ctx, args.String("command"))
}

func printSubCommandHelp(ctx cli.Context) {
    args := ctx.Args()
    printCommandPrefixHelp(ctx, args.String("command"), args.String("subcommand"))
}

func printCommandPrefixHelp(ctx cli.Context, prefix ...string) {
    handler := getHandler(ctx.Handlers(), prefix)

    if handler == nil {
        ExitF("Command not found")
    }

    w := new(tabwriter.Writer)
    w.Init(os.Stdout, 0, 0, 3, ' ', 0)

    fmt.Fprintf(w, "%s\n", handler.Description)
    fmt.Fprintf(w, "%s %s\n", Name, handler.Pattern)
    for _, group := range handler.FlagGroups {
        fmt.Fprintf(w, "\n%s:\n", group.Name)
        for _, flag := range group.Flags {
            boolFlag, isBool := flag.(cli.BoolFlag)
            if isBool && boolFlag.OmitValue {
                fmt.Fprintf(w, "  %s\t%s\n", strings.Join(flag.GetPatterns(), ", "), flag.GetDescription())
            } else {
                fmt.Fprintf(w, "  %s <%s>\t%s\n", strings.Join(flag.GetPatterns(), ", "), flag.GetName(), flag.GetDescription())
            }
        }
    }

    w.Flush()
}

func getHandler(handlers []*cli.Handler, prefix []string) *cli.Handler {
    for _, h := range handlers {
        pattern := stripOptionals(h.SplitPattern())

        if len(prefix) > len(pattern) {
            continue
        }

        if equal(prefix, pattern[:len(prefix)]) {
            return h
        }
    }

    return nil
}

// Strip optional groups (<...>) from pattern
func stripOptionals(pattern []string) []string {
    newArgs := []string{}

    for _, arg := range pattern {
        if strings.HasPrefix(arg, "[") && strings.HasSuffix(arg, "]") {
            continue
        }
        newArgs = append(newArgs, arg)
    }
    return newArgs
}
<|endoftext|>


<commit_before>package highlighter

import (
	"bytes"
	"row"
	"strings"
	"unicode"
)

// Highlight types. Each byte in Row.Render gets assigned
// one of these values, stored in Row.Hl. Used to decide
// what VT-100 escape sequence to print out when displaying
// bytes to screen.
const (
	HL_NORMAL    = 0
	HL_COMMENT   = iota
	HL_MLCOMMENT = iota
	HL_KEYWORD1  = iota
	HL_KEYWORD2  = iota
	HL_STRING    = iota
	HL_NUMBER    = iota
	HL_MATCH     = iota
)

// Syntax instances hold substrings used to do simple
// "syntax coloring" of a file under edit.
type Syntax struct {
	Filetype               string
	filematch              []string
	keywords               []string
	singleLineCommentStart []byte
	multiLineCommentStart  []byte
	multiLineCommentEnd    []byte
	flags                  int
}

var hldb = []Syntax{
	{
		Filetype:  "c",
		filematch: []string{".c", ".h", ".cpp"},
		keywords: []string{"switch", "if", "while", "for",
			"break", "continue", "return", "else", "struct",
			"union", "typedef", "static", "enum", "class", "case",
			"int|", "long|", "double|", "float|", "char|",
			"unsigned|", "signed|", "void|",
		},
		singleLineCommentStart: []byte{'/', '/'},
		multiLineCommentStart:  []byte{'/', '*'},
		multiLineCommentEnd:    []byte{'*', '/'},
		flags:                  HL_HIGHLIGHT_NUMBERS | HL_HIGHLIGHT_STRINGS,
	},
	{
		Filetype:  "Go",
		filematch: []string{".go"},
		keywords: []string{"switch", "if", "for", "select",
			"break", "continue", "return", "else", "struct",
			"type", "case", "select", "func", "var", "import",
			"const", "package",
			"int|", "long|", "double|", "float|", "char|", "byte|",
			"unsigned|", "signed|", "string|", "chan|", "bool|",
			"rune|", "complex|",
		},
		singleLineCommentStart: []byte{'/', '/'},
		multiLineCommentStart:  []byte{'/', '*'},
		multiLineCommentEnd:    []byte{'*', '/'},
		flags:                  HL_HIGHLIGHT_NUMBERS | HL_HIGHLIGHT_STRINGS,
	},
}

const (
	HL_HIGHLIGHT_NUMBERS = 1 << 0
	HL_HIGHLIGHT_STRINGS = 1 << iota
)

var separators = []byte(",.()+-/*=~%<>[]; \t\n\r")

func isSeparator(c byte) bool {
	return bytes.IndexByte(separators, c) >= 0
}

// UpdateSyntax fills in the Row.Hl element with numbers that
// constitute the color the byte with the same index in Row.Render
// should have when displayed.
func (syntax *Syntax) UpdateSyntax(row *row.Row, inCommentNow bool) (updateNextRow bool) {
	row.Hl = make([]byte, row.Rsize)
	if syntax == nil {
		return
	}
	updateNextRow = false
	scs := syntax.singleLineCommentStart
	mcs := syntax.multiLineCommentStart
	mce := syntax.multiLineCommentEnd
	prevSep := true
	inComment := inCommentNow
	var inString byte
	var skip int
	for i, c := range row.Render {
		if skip > 0 {
			skip--
			continue
		}
		if inString == 0 && len(scs) > 0 && !inComment {
			if bytes.HasPrefix(row.Render[i:], scs) {
				for j := i; j < row.Rsize; j++ {
					row.Hl[j] = HL_COMMENT
				}
				break
			}
		}
		if inString == 0 && len(mcs) > 0 && len(mce) > 0 {
			if inComment {
				row.Hl[i] = HL_MLCOMMENT
				if bytes.HasPrefix(row.Render[i:], mce) {
					for l := i; l < i+len(mce); l++ {
						row.Hl[l] = HL_MLCOMMENT
					}
					skip = len(mce)
					inComment = false
					prevSep = true
				}
				continue
			} else if bytes.HasPrefix(row.Render[i:], mcs) {
				for l := i; l < i+len(mcs); l++ {
					row.Hl[l] = HL_MLCOMMENT
				}
				inComment = true
				skip = len(mcs)
			}
		}
		var prevHl byte = HL_NORMAL
		if i > 0 {
			prevHl = row.Hl[i-1]
		}
		if (syntax.flags & HL_HIGHLIGHT_STRINGS) == HL_HIGHLIGHT_STRINGS {
			if inString != 0 {
				row.Hl[i] = HL_STRING
				if c == '\\' && i+1 < row.Rsize {
					row.Hl[i+1] = HL_STRING
					skip = 1
					continue
				}
				if c == inString {
					inString = 0
				}
				prevSep = true
				continue
			} else {
				if c == '"' || c == '\'' {
					inString = c
					row.Hl[i] = HL_STRING
					continue
				}
			}
		}
		if (syntax.flags & HL_HIGHLIGHT_NUMBERS) == HL_HIGHLIGHT_NUMBERS {
			if unicode.IsDigit(rune(c)) &&
				(prevSep || prevHl == HL_NUMBER) ||
				(c == '.' && prevHl == HL_NUMBER) {
				row.Hl[i] = HL_NUMBER
				prevSep = false
				continue
			}
		}
		if prevSep {
			var j int
			var skw string
			for j, skw = range syntax.keywords[:] {
				kw := []byte(skw)
				var color byte = HL_KEYWORD1
				idx := bytes.LastIndexByte(kw, '|')
				if idx > 0 {
					kw = kw[:idx]
					color = HL_KEYWORD2
				}
				klen := len(kw)
				if bytes.HasPrefix(row.Render[i:], kw) &&
					(len(row.Render[i:]) == klen ||
						isSeparator(row.Render[i+klen])) {
					for l := i; l < i+klen; l++ {
						row.Hl[l] = color
					}
					skip = klen - 1
					break
				}
			}
			if j < len(syntax.keywords)-1 {
				prevSep = false
				continue
			}
		}
		prevSep = isSeparator(c)
	}

	updateNextRow = row.HlOpenComment != inComment
	row.HlOpenComment = inComment
	return updateNextRow
}

// SyntaxToColor maps byte values from Row.Hl to the color numbers
// used in VT-100 escape sequences.
func SyntaxToColor(hl byte) int {
	switch hl {
	case HL_COMMENT, HL_MLCOMMENT:
		return 36
	case HL_KEYWORD1:
		return 32
	case HL_KEYWORD2:
		return 33
	case HL_STRING:
		return 35
	case HL_NUMBER:
		return 31
	case HL_MATCH:
		return 34
	}
	return 37
}

// SelectSyntaxHighlight selects an element of array hldb (*Syntax)
// based on the suffix of the filename argument.
func SelectSyntaxHighlight(filename string) *Syntax {
	if filename == "" {
		return nil
	}

	for _, s := range hldb {
		for _, suffix := range s.filematch {
			if strings.HasSuffix(filename, suffix) {
				return &s
			}
		}
	}
	return nil
}
<commit_msg>Fix bug where 1st char after "/*" didn't get highlit.<commit_after>package highlighter

import (
	"bytes"
	"row"
	"strings"
	"unicode"
)

// Highlight types. Each byte in Row.Render gets assigned
// one of these values, stored in Row.Hl. Used to decide
// what VT-100 escape sequence to print out when displaying
// bytes to screen.
const (
	HL_NORMAL    = 0
	HL_COMMENT   = iota
	HL_MLCOMMENT = iota
	HL_KEYWORD1  = iota
	HL_KEYWORD2  = iota
	HL_STRING    = iota
	HL_NUMBER    = iota
	HL_MATCH     = iota
)

// Syntax instances hold substrings used to do simple
// "syntax coloring" of a file under edit.
type Syntax struct {
	Filetype               string
	filematch              []string
	keywords               []string
	singleLineCommentStart []byte
	multiLineCommentStart  []byte
	multiLineCommentEnd    []byte
	flags                  int
}

var hldb = []Syntax{
	{
		Filetype:  "c",
		filematch: []string{".c", ".h", ".cpp"},
		keywords: []string{"switch", "if", "while", "for",
			"break", "continue", "return", "else", "struct",
			"union", "typedef", "static", "enum", "class", "case",
			"int|", "long|", "double|", "float|", "char|",
			"unsigned|", "signed|", "void|",
		},
		singleLineCommentStart: []byte{'/', '/'},
		multiLineCommentStart:  []byte{'/', '*'},
		multiLineCommentEnd:    []byte{'*', '/'},
		flags:                  HL_HIGHLIGHT_NUMBERS | HL_HIGHLIGHT_STRINGS,
	},
	{
		Filetype:  "Go",
		filematch: []string{".go"},
		keywords: []string{"switch", "if", "for", "select",
			"break", "continue", "return", "else", "struct",
			"type", "case", "select", "func", "var", "import",
			"const", "package",
			"int|", "long|", "double|", "float|", "char|", "byte|",
			"unsigned|", "signed|", "string|", "chan|", "bool|",
			"rune|", "complex|",
		},
		singleLineCommentStart: []byte{'/', '/'},
		multiLineCommentStart:  []byte{'/', '*'},
		multiLineCommentEnd:    []byte{'*', '/'},
		flags:                  HL_HIGHLIGHT_NUMBERS | HL_HIGHLIGHT_STRINGS,
	},
}

const (
	HL_HIGHLIGHT_NUMBERS = 1 << 0
	HL_HIGHLIGHT_STRINGS = 1 << iota
)

var separators = []byte(",.()+-/*=~%<>[]; \t\n\r")

func isSeparator(c byte) bool {
	return bytes.IndexByte(separators, c) >= 0
}

// UpdateSyntax fills in the Row.Hl element with numbers that
// constitute the color the byte with the same index in Row.Render
// should have when displayed.
func (syntax *Syntax) UpdateSyntax(row *row.Row, inCommentNow bool) (updateNextRow bool) {
	row.Hl = make([]byte, row.Rsize)
	if syntax == nil {
		return
	}
	updateNextRow = false
	scs := syntax.singleLineCommentStart
	mcs := syntax.multiLineCommentStart
	mce := syntax.multiLineCommentEnd
	prevSep := true
	inComment := inCommentNow
	var inString byte
	var skip int
	for i, c := range row.Render {
		if skip > 0 {
			skip--
			continue
		}
		if inString == 0 && len(scs) > 0 && !inComment {
			if bytes.HasPrefix(row.Render[i:], scs) {
				for j := i; j < row.Rsize; j++ {
					row.Hl[j] = HL_COMMENT
				}
				break
			}
		}
		if inString == 0 && len(mcs) > 0 && len(mce) > 0 {
			if inComment {
				row.Hl[i] = HL_MLCOMMENT
				if bytes.HasPrefix(row.Render[i:], mce) {
					for l := i; l < i+len(mce); l++ {
						row.Hl[l] = HL_MLCOMMENT
					}
					skip = len(mce)
					inComment = false
					prevSep = true
				}
				continue
			} else if bytes.HasPrefix(row.Render[i:], mcs) {
				for l := i; l < i+len(mcs); l++ {
					row.Hl[l] = HL_MLCOMMENT
				}
				inComment = true
				skip = len(mcs) - 1
			}
		}
		var prevHl byte = HL_NORMAL
		if i > 0 {
			prevHl = row.Hl[i-1]
		}
		if (syntax.flags & HL_HIGHLIGHT_STRINGS) == HL_HIGHLIGHT_STRINGS {
			if inString != 0 {
				row.Hl[i] = HL_STRING
				if c == '\\' && i+1 < row.Rsize {
					row.Hl[i+1] = HL_STRING
					skip = 1
					continue
				}
				if c == inString {
					inString = 0
				}
				prevSep = true
				continue
			} else {
				if c == '"' || c == '\'' {
					inString = c
					row.Hl[i] = HL_STRING
					continue
				}
			}
		}
		if (syntax.flags & HL_HIGHLIGHT_NUMBERS) == HL_HIGHLIGHT_NUMBERS {
			if unicode.IsDigit(rune(c)) &&
				(prevSep || prevHl == HL_NUMBER) ||
				(c == '.' && prevHl == HL_NUMBER) {
				row.Hl[i] = HL_NUMBER
				prevSep = false
				continue
			}
		}
		if prevSep {
			var j int
			var skw string
			for j, skw = range syntax.keywords[:] {
				kw := []byte(skw)
				var color byte = HL_KEYWORD1
				idx := bytes.LastIndexByte(kw, '|')
				if idx > 0 {
					kw = kw[:idx]
					color = HL_KEYWORD2
				}
				klen := len(kw)
				if bytes.HasPrefix(row.Render[i:], kw) &&
					(len(row.Render[i:]) == klen ||
						isSeparator(row.Render[i+klen])) {
					for l := i; l < i+klen; l++ {
						row.Hl[l] = color
					}
					skip = klen - 1
					break
				}
			}
			if j < len(syntax.keywords)-1 {
				prevSep = false
				continue
			}
		}
		prevSep = isSeparator(c)
	}

	updateNextRow = row.HlOpenComment != inComment
	row.HlOpenComment = inComment
	return updateNextRow
}

// SyntaxToColor maps byte values from Row.Hl to the color numbers
// used in VT-100 escape sequences.
func SyntaxToColor(hl byte) int {
	switch hl {
	case HL_COMMENT, HL_MLCOMMENT:
		return 36
	case HL_KEYWORD1:
		return 32
	case HL_KEYWORD2:
		return 33
	case HL_STRING:
		return 35
	case HL_NUMBER:
		return 31
	case HL_MATCH:
		return 34
	}
	return 37
}

// SelectSyntaxHighlight selects an element of array hldb (*Syntax)
// based on the suffix of the filename argument.
func SelectSyntaxHighlight(filename string) *Syntax {
	if filename == "" {
		return nil
	}

	for _, s := range hldb {
		for _, suffix := range s.filematch {
			if strings.HasSuffix(filename, suffix) {
				return &s
			}
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package goharproxy

import (
	"testing"
	"net/http"
	"net/http/httptest"
	"net/url"
	"crypto/tls"
	"io"
	"log"
	"encoding/json"
	"fmt"
	"net"
	"strconv"
	"bytes"
	"io/ioutil"
	"strings"
)

var acceptAllCerts = &tls.Config{InsecureSkipVerify: true}
var srv = httptest.NewServer(nil)

func init() {
	http.DefaultServeMux.Handle("/bobo", ConstantHanlder("bobo"))
	http.DefaultServeMux.Handle("/query", QueryHandler{})
	http.DefaultServeMux.Handle("/", ConstantHanlder("google"))
}

type QueryHandler struct{}

func (QueryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if err := req.ParseForm(); err != nil {
		panic(err)
	}
	io.WriteString(w, req.Form.Get("result"))
}

type ConstantHanlder string

func (h ConstantHanlder) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, string(h))
}
// HarProxy Tests

func TestHttpHarProxyGetIpEntries(t *testing.T) {
	client, harProxy, s := oneShotProxy()
	defer s.Close()

	testUrl , _ := url.Parse(srv.URL + "/bobo")
	_, err := client.Get(testUrl.String())
	if err != nil {
		t.Fatal(err)
	}
	harLog := testLog(t, harProxy.NewHarReader())
	host, _, _ := net.SplitHostPort(testUrl.Host)
	testIpAddr(t, host, harLog)
}

func TestHttpHarProxyGetHostEntries(t *testing.T) {
	client, harProxy, s := oneShotProxy()
	defer s.Close()

	_, err := client.Get("http://www.google.com")
	if err != nil {
		t.Fatal(err)
	}
	ipaddr, ipErr := net.LookupIP("www.google.com")
	if ipErr != nil {
		t.Fatal(ipErr)
	}
	if len(ipaddr) == 0 {
		t.Fatal("Didn't get ip for www.google.com")
	}
	harLog := testLog(t, harProxy.NewHarReader())
	testIpAddr(t, ipaddr[0].String(), harLog)
}

func testIpAddr(t *testing.T, expected string, harLog *HarLog) {
	actual := harLog.Entries[0].ServerIpAddress
	if actual != expected {
		t.Fatal("Expected to get host: ", expected, " but got: ", actual)
	}
}

// HarProxyServer tests

func TestHarProxyServerGetProxyAndDelete(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, _ := getProxiedClient(t, harProxyServer, testClient)
	proxyServerDeleteUrl := fmt.Sprintf("%v/proxy/%v", harProxyServer.URL, proxyServerPort.Port)
	req , reqErr := http.NewRequest("DELETE", proxyServerDeleteUrl, nil)
	if reqErr != nil {
		t.Fatal(reqErr)
	}
	resp, respErr := testClient.Do(req)
	testResp(t, resp, respErr)

	var proxyServerMessage *ProxyServerMessage = new(ProxyServerMessage)
	json.NewDecoder(resp.Body).Decode(proxyServerMessage)

	if proxyServerMessage.Message != fmt.Sprintf("Deleted proxy for port [%v] succesfully", proxyServerPort.Port) {
		t.Fatal("Did not get delete message")
	}
}

func TestHarProxyServerSendInvalidMessage(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerUrl := fmt.Sprintf("%v/bla", harProxyServer.URL)
	resp , err := testClient.Get(proxyServerUrl)
	if err != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != http.StatusNotFound {
		t.Fatal("Did not get 404 status code")
	}

	var proxyErrorMessage *ProxyServerErr = new(ProxyServerErr)
	json.NewDecoder(resp.Body).Decode(proxyErrorMessage)

	if proxyErrorMessage.Error != fmt.Sprintf("No such path: [%v]", "/bla") {
		t.Fatal("Did not get expected error message")
	}
}

func TestHarProxyServerGetInvalidProxy(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerHarUrl := fmt.Sprintf("%v/proxy/%v/har", harProxyServer.URL, 9999)
	req , err := http.NewRequest("PUT", proxyServerHarUrl, nil)
	if err != nil {
		t.Fatal(err)
	}
	resp, respErr := testClient.Do(req)
	if respErr != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != http.StatusNotFound {
		t.Fatal("Did not get 404 status code")
	}

	var proxyErrorMessage *ProxyServerErr = new(ProxyServerErr)
	json.NewDecoder(resp.Body).Decode(proxyErrorMessage)

	if proxyErrorMessage.Error != fmt.Sprintf("No proxy for port [%v]", 9999) {
		t.Fatal("Did not get expected error message")
	}
}

func TestHarProxyServerSendInvalidProxyMessage(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, _ := getProxiedClient(t, harProxyServer, testClient)
	proxyServerHarUrl := fmt.Sprintf("%v/proxy/%v/bla", harProxyServer.URL, proxyServerPort.Port)
	req , reqErr := http.NewRequest("PUT", proxyServerHarUrl, nil)
	if reqErr != nil {
		t.Fatal(reqErr)
	}
	resp, respErr := testClient.Do(req)
	if respErr != nil {
		t.Fatal(respErr)
	}
	if resp.StatusCode != http.StatusNotFound {
		t.Fatal("Did not get 404 status code")
	}

	var proxyErrorMessage *ProxyServerErr = new(ProxyServerErr)
	json.NewDecoder(resp.Body).Decode(proxyErrorMessage)

	if proxyErrorMessage.Error != "No such path [/bla] with method PUT" {
		t.Fatal("Did not get expected error message")
	}
}

func TestHarProxyServerGetProxyAndEntries(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, proxiedClient := getProxiedClient(t, harProxyServer, testClient)
	_, err := proxiedClient.Get(srv.URL + "/bobo")
	if err != nil {
		t.Fatal(err)
	}

	proxyServerHarUrl := fmt.Sprintf("%v/proxy/%v/har", harProxyServer.URL, proxyServerPort.Port)
	req , reqErr := http.NewRequest("PUT", proxyServerHarUrl, nil)
	if reqErr != nil {
		t.Fatal(reqErr)
	}
	resp, respErr := testClient.Do(req)
	testResp(t, resp, respErr)
	testLog(t, resp.Body)
}

func TestHarProxyServerGetProxyAndEntriesWithResponseContent(t *testing.T) {
	captureContent = true
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, proxiedClient := getProxiedClient(t, harProxyServer, testClient)
	resp, err := proxiedClient.Get(srv.URL + "/query?result=bla")
	if err != nil {
		t.Fatal(err)
	}
	txt, err  := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatal("Error reading response body")
	}
	if string(txt) != "bla" {
		t.Fatal("Expect to get bla in response body")
	}

	proxyServerHarUrl := fmt.Sprintf("%v/proxy/%v/har", harProxyServer.URL, proxyServerPort.Port)
	req , reqErr := http.NewRequest("PUT", proxyServerHarUrl, nil)
	if reqErr != nil {
		t.Fatal(reqErr)
	}
	resp, err = testClient.Do(req)
	testResp(t, resp, err)

	harLog := testLog(t, resp.Body)
	if harLog.Entries[0].Response.Content.Text != "bla" {
		t.Fatal("Expect to get bla in har response")
	}

}

func TestHarProxyServerGetProxyAndEntriesWithRequestPostData(t *testing.T) {
	captureContent = true
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, proxiedClient := getProxiedClient(t, harProxyServer, testClient)
	resp, err := proxiedClient.Post(srv.URL + "/bobo", "form-data", strings.NewReader("bla"))
	if err != nil {
		t.Fatal(err)
	}

	proxyServerHarUrl := fmt.Sprintf("%v/proxy/%v/har", harProxyServer.URL, proxyServerPort.Port)
	req , reqErr := http.NewRequest("PUT", proxyServerHarUrl, nil)
	if reqErr != nil {
		t.Fatal(reqErr)
	}
	resp, err = testClient.Do(req)
	testResp(t, resp, err)

	harLog := testLog(t, resp.Body)
	if harLog.Entries[0].Request.PostData.Text!= "bla" {
		t.Fatal("Expect to get bla in har request")
	}

}

func TestHarProxyServerGetProxyChangeHost(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, proxiedClient := getProxiedClient(t, harProxyServer, testClient)
	proxyServerHostUrl := fmt.Sprintf("%v/proxy/%v/hosts", harProxyServer.URL, proxyServerPort.Port)

	srvUrl , _ := url.Parse(srv.URL)
	proxyHosts := []ProxyHosts{{Host : "www.google.com", NewHost : srvUrl.Host}}
	proxyHostsJson, _ := json.Marshal(&proxyHosts)
	buffer := bytes.NewBuffer(proxyHostsJson)
	_, err := testClient.Post(proxyServerHostUrl, "application/json", buffer)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := proxiedClient.Get("http://www.google.com")
	testResp(t, resp, err)

	str, _ := ioutil.ReadAll(resp.Body)
	if string(str) != "google" {
		t.Fatal("Failed redirecting request")
	}
}

func getProxiedClient(t *testing.T, harProxyServer *httptest.Server, testClient *http.Client) (proxyServerPort *ProxyServerPort, client *http.Client) {
	resp, err := testClient.Post(harProxyServer.URL + "/proxy", "", nil)
	testResp(t, resp, err)

	proxyServerPort = new(ProxyServerPort)
	if e := json.NewDecoder(resp.Body).Decode(proxyServerPort); e != nil {
		log.Fatal(e)
	}

	host, _, _ := net.SplitHostPort(harProxyServer.URL)
	proxyUrl, _ := url.Parse(host + ":" + strconv.Itoa(proxyServerPort.Port))
	client = newProxyHttpTestClient(proxyUrl)
	return
}

func testLog(t *testing.T, r io.Reader) *HarLog{
	var harLog *HarLog = new(HarLog)
	json.NewDecoder(r).Decode(harLog)
	log.Printf("Har entries len: %v", len(harLog.Entries))
	if len(harLog.Entries) == 0 {
		t.Fatal("Didn't get valid har entries")
	}
	return harLog
}

func testResp(t *testing.T, resp *http.Response, err error) {
	if err != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != http.StatusOK {
		t.Fatal(resp.Status)
	}
}

func oneShotProxy() (client *http.Client, harProxy *HarProxy, s *httptest.Server) {
	harProxy = NewHarProxy()
	client, s = newProxyHttpTestServer(harProxy)
	return
}

func newProxyTestServer() (client *http.Client, s *httptest.Server) {
	s = httptest.NewServer(http.HandlerFunc(proxyHandler))

	tr := &http.Transport{TLSClientConfig: acceptAllCerts}
	client = &http.Client{Transport: tr}
	return
}

func newProxyHttpTestServer(harProxy *HarProxy) (client *http.Client, s *httptest.Server) {
	s = httptest.NewServer(harProxy.Proxy)
	proxyUrl, _ := url.Parse(s.URL)
	client = newProxyHttpTestClient(proxyUrl)
	return
}

func newProxyHttpTestClient(proxyUrl *url.URL) (client *http.Client) {
	log.Println(proxyUrl)
	tr := &http.Transport{TLSClientConfig: acceptAllCerts, Proxy: http.ProxyURL(proxyUrl)}
	client = &http.Client{Transport: tr}
	return
}
<commit_msg>Test for valid ip address in host test instead of equals to other ip.<commit_after>package goharproxy

import (
	"testing"
	"net/http"
	"net/http/httptest"
	"net/url"
	"crypto/tls"
	"io"
	"log"
	"encoding/json"
	"fmt"
	"net"
	"strconv"
	"bytes"
	"io/ioutil"
	"strings"
)

var acceptAllCerts = &tls.Config{InsecureSkipVerify: true}
var srv = httptest.NewServer(nil)

func init() {
	http.DefaultServeMux.Handle("/bobo", ConstantHanlder("bobo"))
	http.DefaultServeMux.Handle("/query", QueryHandler{})
	http.DefaultServeMux.Handle("/", ConstantHanlder("google"))
}

type QueryHandler struct{}

func (QueryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if err := req.ParseForm(); err != nil {
		panic(err)
	}
	io.WriteString(w, req.Form.Get("result"))
}

type ConstantHanlder string

func (h ConstantHanlder) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	io.WriteString(w, string(h))
}
// HarProxy Tests

func TestHttpHarProxyGetIpEntries(t *testing.T) {
	client, harProxy, s := oneShotProxy()
	defer s.Close()

	testUrl , _ := url.Parse(srv.URL + "/bobo")
	_, err := client.Get(testUrl.String())
	if err != nil {
		t.Fatal(err)
	}
	harLog := testLog(t, harProxy.NewHarReader())
	host, _, _ := net.SplitHostPort(testUrl.Host)
	if harLog.Entries[0].ServerIpAddress != host {
		t.Fatal("Expected to get host: ", host, " but got: ", harLog.Entries[0].ServerIpAddress)
	}
}

func TestHttpHarProxyGetHostEntries(t *testing.T) {
	client, harProxy, s := oneShotProxy()
	defer s.Close()

	_, err := client.Get("http://www.google.com")
	if err != nil {
		t.Fatal(err)
	}
	ipaddr, ipErr := net.LookupIP("www.google.com")
	if ipErr != nil {
		t.Fatal(ipErr)
	}
	if len(ipaddr) == 0 {
		t.Fatal("Didn't get ip for www.google.com")
	}
	harLog := testLog(t, harProxy.NewHarReader())
	if ip := net.ParseIP(harLog.Entries[0].ServerIpAddress); ip == nil {
		t.Fatal("Expected to get valid ip address in har ServerIpAddress")
	}
}

// HarProxyServer tests

func TestHarProxyServerGetProxyAndDelete(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, _ := getProxiedClient(t, harProxyServer, testClient)
	proxyServerDeleteUrl := fmt.Sprintf("%v/proxy/%v", harProxyServer.URL, proxyServerPort.Port)
	req , reqErr := http.NewRequest("DELETE", proxyServerDeleteUrl, nil)
	if reqErr != nil {
		t.Fatal(reqErr)
	}
	resp, respErr := testClient.Do(req)
	testResp(t, resp, respErr)

	var proxyServerMessage *ProxyServerMessage = new(ProxyServerMessage)
	json.NewDecoder(resp.Body).Decode(proxyServerMessage)

	if proxyServerMessage.Message != fmt.Sprintf("Deleted proxy for port [%v] succesfully", proxyServerPort.Port) {
		t.Fatal("Did not get delete message")
	}
}

func TestHarProxyServerSendInvalidMessage(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerUrl := fmt.Sprintf("%v/bla", harProxyServer.URL)
	resp , err := testClient.Get(proxyServerUrl)
	if err != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != http.StatusNotFound {
		t.Fatal("Did not get 404 status code")
	}

	var proxyErrorMessage *ProxyServerErr = new(ProxyServerErr)
	json.NewDecoder(resp.Body).Decode(proxyErrorMessage)

	if proxyErrorMessage.Error != fmt.Sprintf("No such path: [%v]", "/bla") {
		t.Fatal("Did not get expected error message")
	}
}

func TestHarProxyServerGetInvalidProxy(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerHarUrl := fmt.Sprintf("%v/proxy/%v/har", harProxyServer.URL, 9999)
	req , err := http.NewRequest("PUT", proxyServerHarUrl, nil)
	if err != nil {
		t.Fatal(err)
	}
	resp, respErr := testClient.Do(req)
	if respErr != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != http.StatusNotFound {
		t.Fatal("Did not get 404 status code")
	}

	var proxyErrorMessage *ProxyServerErr = new(ProxyServerErr)
	json.NewDecoder(resp.Body).Decode(proxyErrorMessage)

	if proxyErrorMessage.Error != fmt.Sprintf("No proxy for port [%v]", 9999) {
		t.Fatal("Did not get expected error message")
	}
}

func TestHarProxyServerSendInvalidProxyMessage(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, _ := getProxiedClient(t, harProxyServer, testClient)
	proxyServerHarUrl := fmt.Sprintf("%v/proxy/%v/bla", harProxyServer.URL, proxyServerPort.Port)
	req , reqErr := http.NewRequest("PUT", proxyServerHarUrl, nil)
	if reqErr != nil {
		t.Fatal(reqErr)
	}
	resp, respErr := testClient.Do(req)
	if respErr != nil {
		t.Fatal(respErr)
	}
	if resp.StatusCode != http.StatusNotFound {
		t.Fatal("Did not get 404 status code")
	}

	var proxyErrorMessage *ProxyServerErr = new(ProxyServerErr)
	json.NewDecoder(resp.Body).Decode(proxyErrorMessage)

	if proxyErrorMessage.Error != "No such path [/bla] with method PUT" {
		t.Fatal("Did not get expected error message")
	}
}

func TestHarProxyServerGetProxyAndEntries(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, proxiedClient := getProxiedClient(t, harProxyServer, testClient)
	_, err := proxiedClient.Get(srv.URL + "/bobo")
	if err != nil {
		t.Fatal(err)
	}

	proxyServerHarUrl := fmt.Sprintf("%v/proxy/%v/har", harProxyServer.URL, proxyServerPort.Port)
	req , reqErr := http.NewRequest("PUT", proxyServerHarUrl, nil)
	if reqErr != nil {
		t.Fatal(reqErr)
	}
	resp, respErr := testClient.Do(req)
	testResp(t, resp, respErr)
	testLog(t, resp.Body)
}

func TestHarProxyServerGetProxyAndEntriesWithResponseContent(t *testing.T) {
	captureContent = true
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, proxiedClient := getProxiedClient(t, harProxyServer, testClient)
	resp, err := proxiedClient.Get(srv.URL + "/query?result=bla")
	if err != nil {
		t.Fatal(err)
	}
	txt, err  := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatal("Error reading response body")
	}
	if string(txt) != "bla" {
		t.Fatal("Expect to get bla in response body")
	}

	proxyServerHarUrl := fmt.Sprintf("%v/proxy/%v/har", harProxyServer.URL, proxyServerPort.Port)
	req , reqErr := http.NewRequest("PUT", proxyServerHarUrl, nil)
	if reqErr != nil {
		t.Fatal(reqErr)
	}
	resp, err = testClient.Do(req)
	testResp(t, resp, err)

	harLog := testLog(t, resp.Body)
	if harLog.Entries[0].Response.Content.Text != "bla" {
		t.Fatal("Expect to get bla in har response")
	}

}

func TestHarProxyServerGetProxyAndEntriesWithRequestPostData(t *testing.T) {
	captureContent = true
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, proxiedClient := getProxiedClient(t, harProxyServer, testClient)
	resp, err := proxiedClient.Post(srv.URL + "/bobo", "form-data", strings.NewReader("bla"))
	if err != nil {
		t.Fatal(err)
	}

	proxyServerHarUrl := fmt.Sprintf("%v/proxy/%v/har", harProxyServer.URL, proxyServerPort.Port)
	req , reqErr := http.NewRequest("PUT", proxyServerHarUrl, nil)
	if reqErr != nil {
		t.Fatal(reqErr)
	}
	resp, err = testClient.Do(req)
	testResp(t, resp, err)

	harLog := testLog(t, resp.Body)
	if harLog.Entries[0].Request.PostData.Text!= "bla" {
		t.Fatal("Expect to get bla in har request")
	}

}

func TestHarProxyServerGetProxyChangeHost(t *testing.T) {
	testClient, harProxyServer := newProxyTestServer()
	defer harProxyServer.Close()

	proxyServerPort, proxiedClient := getProxiedClient(t, harProxyServer, testClient)
	proxyServerHostUrl := fmt.Sprintf("%v/proxy/%v/hosts", harProxyServer.URL, proxyServerPort.Port)

	srvUrl , _ := url.Parse(srv.URL)
	proxyHosts := []ProxyHosts{{Host : "www.google.com", NewHost : srvUrl.Host}}
	proxyHostsJson, _ := json.Marshal(&proxyHosts)
	buffer := bytes.NewBuffer(proxyHostsJson)
	_, err := testClient.Post(proxyServerHostUrl, "application/json", buffer)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := proxiedClient.Get("http://www.google.com")
	testResp(t, resp, err)

	str, _ := ioutil.ReadAll(resp.Body)
	if string(str) != "google" {
		t.Fatal("Failed redirecting request")
	}
}

func getProxiedClient(t *testing.T, harProxyServer *httptest.Server, testClient *http.Client) (proxyServerPort *ProxyServerPort, client *http.Client) {
	resp, err := testClient.Post(harProxyServer.URL + "/proxy", "", nil)
	testResp(t, resp, err)

	proxyServerPort = new(ProxyServerPort)
	if e := json.NewDecoder(resp.Body).Decode(proxyServerPort); e != nil {
		log.Fatal(e)
	}

	host, _, _ := net.SplitHostPort(harProxyServer.URL)
	proxyUrl, _ := url.Parse(host + ":" + strconv.Itoa(proxyServerPort.Port))
	client = newProxyHttpTestClient(proxyUrl)
	return
}

func testLog(t *testing.T, r io.Reader) *HarLog{
	var harLog *HarLog = new(HarLog)
	json.NewDecoder(r).Decode(harLog)
	log.Printf("Har entries len: %v", len(harLog.Entries))
	if len(harLog.Entries) == 0 {
		t.Fatal("Didn't get valid har entries")
	}
	return harLog
}

func testResp(t *testing.T, resp *http.Response, err error) {
	if err != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != http.StatusOK {
		t.Fatal(resp.Status)
	}
}

func oneShotProxy() (client *http.Client, harProxy *HarProxy, s *httptest.Server) {
	harProxy = NewHarProxy()
	client, s = newProxyHttpTestServer(harProxy)
	return
}

func newProxyTestServer() (client *http.Client, s *httptest.Server) {
	s = httptest.NewServer(http.HandlerFunc(proxyHandler))

	tr := &http.Transport{TLSClientConfig: acceptAllCerts}
	client = &http.Client{Transport: tr}
	return
}

func newProxyHttpTestServer(harProxy *HarProxy) (client *http.Client, s *httptest.Server) {
	s = httptest.NewServer(harProxy.Proxy)
	proxyUrl, _ := url.Parse(s.URL)
	client = newProxyHttpTestClient(proxyUrl)
	return
}

func newProxyHttpTestClient(proxyUrl *url.URL) (client *http.Client) {
	log.Println(proxyUrl)
	tr := &http.Transport{TLSClientConfig: acceptAllCerts, Proxy: http.ProxyURL(proxyUrl)}
	client = &http.Client{Transport: tr}
	return
}
<|endoftext|>


<commit_before><commit_msg>Fixup stray LB infix refs<commit_after><|endoftext|>


<commit_before>// package metricbatcher provides a mechanism to batch counter updates into a single event.
package metricbatcher

import (
	"github.com/cloudfoundry/dropsonde/metric_sender"
	"sync"
	"time"
)

// MetricBatcher batches counter increment/add calls into periodic, aggregate events.
type MetricBatcher struct {
	metrics      map[string]uint64
	batchTicker  *time.Ticker
	metricSender metric_sender.MetricSender
	lock         sync.RWMutex
}

// New instantiates a running MetricBatcher. Eventswill be emitted once per batchDuration. All
// updates to a given counter name will be combined into a single event and sent to metricSender.
func New(metricSender metric_sender.MetricSender, batchDuration time.Duration) *MetricBatcher {
	mb := &MetricBatcher{
		metrics:      make(map[string]uint64),
		batchTicker:  time.NewTicker(batchDuration),
		metricSender: metricSender,
	}

	go func() {
		for {
			<-mb.batchTicker.C
			mb.lock.Lock()

			for name, delta := range mb.metrics {
				metricSender.AddToCounter(name, delta)
			}
			mb.unsafeReset()

			mb.lock.Unlock()
		}
	}()

	return mb
}

// BatchIncrementCounter increments the named counter by 1, but does not immediately send a
// CounterEvent.
func (mb *MetricBatcher) BatchIncrementCounter(name string) {
	mb.BatchAddCounter(name, 1)
}

// BatchAddCounter increments the named counter by the provided delta, but does not
// immediately send a CounterEvent.
func (mb *MetricBatcher) BatchAddCounter(name string, delta uint64) {
	mb.lock.Lock()
	defer mb.lock.Unlock()

	mb.metrics[name] += delta
}

// Reset clears the MetricBatcher's internal state, so that no counters are tracked.
func (mb *MetricBatcher) Reset() {
	mb.lock.Lock()
	defer mb.lock.Unlock()

	mb.unsafeReset()
}

func (mb *MetricBatcher) unsafeReset() {
	mb.metrics = make(map[string]uint64, len(mb.metrics))
}
<commit_msg>Refactor batcher go proc to have uniform locking<commit_after>// package metricbatcher provides a mechanism to batch counter updates into a single event.
package metricbatcher

import (
	"github.com/cloudfoundry/dropsonde/metric_sender"
	"sync"
	"time"
)

// MetricBatcher batches counter increment/add calls into periodic, aggregate events.
type MetricBatcher struct {
	metrics      map[string]uint64
	batchTicker  *time.Ticker
	metricSender metric_sender.MetricSender
	lock         sync.RWMutex
}

// New instantiates a running MetricBatcher. Eventswill be emitted once per batchDuration. All
// updates to a given counter name will be combined into a single event and sent to metricSender.
func New(metricSender metric_sender.MetricSender, batchDuration time.Duration) *MetricBatcher {
	mb := &MetricBatcher{
		metrics:      make(map[string]uint64),
		batchTicker:  time.NewTicker(batchDuration),
		metricSender: metricSender,
	}

	go func() {
		for {
			<-mb.batchTicker.C
			mb.sendBatch()
		}
	}()

	return mb
}

func (mb *MetricBatcher) sendBatch() {
	mb.lock.Lock()
	defer mb.lock.Unlock()

	for name, delta := range mb.metrics {
		mb.metricSender.AddToCounter(name, delta)
	}
	mb.unsafeReset()
}

// BatchIncrementCounter increments the named counter by 1, but does not immediately send a
// CounterEvent.
func (mb *MetricBatcher) BatchIncrementCounter(name string) {
	mb.BatchAddCounter(name, 1)
}

// BatchAddCounter increments the named counter by the provided delta, but does not
// immediately send a CounterEvent.
func (mb *MetricBatcher) BatchAddCounter(name string, delta uint64) {
	mb.lock.Lock()
	defer mb.lock.Unlock()

	mb.metrics[name] += delta
}

// Reset clears the MetricBatcher's internal state, so that no counters are tracked.
func (mb *MetricBatcher) Reset() {
	mb.lock.Lock()
	defer mb.lock.Unlock()

	mb.unsafeReset()
}

func (mb *MetricBatcher) unsafeReset() {
	mb.metrics = make(map[string]uint64, len(mb.metrics))
}
<|endoftext|>


<commit_before>// Package accesstoken provides storage and validation of Chain Core
// credentials.
package accesstoken

import (
	"context"
	"crypto/rand"
	"encoding/json"
	"fmt"
	"regexp"
	"strings"
	"time"

	dbm "github.com/tendermint/tmlibs/db"

	"github.com/bytom/crypto/sha3pool"
	"github.com/bytom/errors"
)

const tokenSize = 32

var (
	// ErrBadID is returned when Create is called on an invalid id string.
	ErrBadID = errors.New("invalid id")
	// ErrDuplicateID is returned when Create is called on an existing ID.
	ErrDuplicateID = errors.New("duplicate access token ID")
	// ErrBadType is returned when Create is called with a bad type.
	ErrBadType = errors.New("type must be client or network")
	// ErrNoMatchID is returned when Delete is called on nonexisting ID.
	ErrNoMatchID = errors.New("nonexisting access token ID")
	// ErrInvalidToken is returned when Check is called on invalid token
	ErrInvalidToken = errors.New("invalid token")

	// validIDRegexp checks that all characters are alphumeric, _ or -.
	// It also must have a length of at least 1.
	validIDRegexp = regexp.MustCompile(`^[\w-]+$`)
)

// Token describe the access token.
type Token struct {
	ID      string    `json:"id"`
	Token   string    `json:"token,omitempty"`
	Type    string    `json:"type,omitempty"`
	Created time.Time `json:"created_at"`
}

// CredentialStore store user access credential.
type CredentialStore struct {
	DB dbm.DB
}

// NewStore creates and returns a new Store object.
func NewStore(db dbm.DB) *CredentialStore {
	return &CredentialStore{
		DB: db,
	}
}

// Create generates a new access token with the given ID.
func (cs *CredentialStore) Create(ctx context.Context, id, typ string) (*Token, error) {
	if !validIDRegexp.MatchString(id) {
		return nil, errors.WithDetailf(ErrBadID, "invalid id %q", id)
	}

	key := []byte(id)
	if cs.DB.Get(key) != nil {
		return nil, errors.WithDetailf(ErrDuplicateID, "id %q already in use", id)
	}

	secret := make([]byte, tokenSize)
	if _, err := rand.Read(secret); err != nil {
		return nil, err
	}

	hashedSecret := make([]byte, tokenSize)
	sha3pool.Sum256(hashedSecret, secret)

	token := &Token{
		ID:      id,
		Token:   fmt.Sprintf("%s:%x", id, hashedSecret),
		Type:    typ,
		Created: time.Now(),
	}

	value, err := json.Marshal(token)
	if err != nil {
		return nil, err
	}
	cs.DB.Set(key, value)

	return token, nil
}

// Check returns whether or not an id-secret pair is a valid access token.
func (cs *CredentialStore) Check(ctx context.Context, id string, secret string) (bool, error) {
	if !validIDRegexp.MatchString(id) {
		return false, errors.WithDetailf(ErrBadID, "invalid id %q", id)
	}

	var value []byte
	token := &Token{}

	if value = cs.DB.Get([]byte(id)); value == nil {
		return false, errors.WithDetailf(ErrNoMatchID, "check id %q nonexisting", id)
	}
	if err := json.Unmarshal(value, token); err != nil {
		return false, err
	}

	if strings.Compare(strings.Split(token.Token, ":")[1], secret) == 0 {
		return true, nil
	}

	return false, ErrInvalidToken
}

// List lists all access tokens.
func (cs *CredentialStore) List(ctx context.Context) ([]*Token, error) {
	tokens := make([]*Token, 0)
	iter := cs.DB.Iterator()
	defer iter.Release()

	for iter.Next() {
		token := &Token{}
		if err := json.Unmarshal(iter.Value(), token); err != nil {
			return nil, err
		}
		tokens = append(tokens, token)
	}
	return tokens, nil
}

// Delete deletes an access token by id.
func (cs *CredentialStore) Delete(ctx context.Context, id string) error {
	if !validIDRegexp.MatchString(id) {
		return errors.WithDetailf(ErrBadID, "invalid id %q", id)
	}

	cs.DB.Delete([]byte(id))
	return nil
}
<commit_msg>fix delete non exist token id successfully<commit_after>// Package accesstoken provides storage and validation of Chain Core
// credentials.
package accesstoken

import (
	"context"
	"crypto/rand"
	"encoding/json"
	"fmt"
	"regexp"
	"strings"
	"time"

	dbm "github.com/tendermint/tmlibs/db"

	"github.com/bytom/crypto/sha3pool"
	"github.com/bytom/errors"
)

const tokenSize = 32

var (
	// ErrBadID is returned when Create is called on an invalid id string.
	ErrBadID = errors.New("invalid id")
	// ErrDuplicateID is returned when Create is called on an existing ID.
	ErrDuplicateID = errors.New("duplicate access token ID")
	// ErrBadType is returned when Create is called with a bad type.
	ErrBadType = errors.New("type must be client or network")
	// ErrNoMatchID is returned when Delete is called on nonexisting ID.
	ErrNoMatchID = errors.New("nonexisting access token ID")
	// ErrInvalidToken is returned when Check is called on invalid token
	ErrInvalidToken = errors.New("invalid token")

	// validIDRegexp checks that all characters are alphumeric, _ or -.
	// It also must have a length of at least 1.
	validIDRegexp = regexp.MustCompile(`^[\w-]+$`)
)

// Token describe the access token.
type Token struct {
	ID      string    `json:"id"`
	Token   string    `json:"token,omitempty"`
	Type    string    `json:"type,omitempty"`
	Created time.Time `json:"created_at"`
}

// CredentialStore store user access credential.
type CredentialStore struct {
	DB dbm.DB
}

// NewStore creates and returns a new Store object.
func NewStore(db dbm.DB) *CredentialStore {
	return &CredentialStore{
		DB: db,
	}
}

// Create generates a new access token with the given ID.
func (cs *CredentialStore) Create(ctx context.Context, id, typ string) (*Token, error) {
	if !validIDRegexp.MatchString(id) {
		return nil, errors.WithDetailf(ErrBadID, "invalid id %q", id)
	}

	key := []byte(id)
	if cs.DB.Get(key) != nil {
		return nil, errors.WithDetailf(ErrDuplicateID, "id %q already in use", id)
	}

	secret := make([]byte, tokenSize)
	if _, err := rand.Read(secret); err != nil {
		return nil, err
	}

	hashedSecret := make([]byte, tokenSize)
	sha3pool.Sum256(hashedSecret, secret)

	token := &Token{
		ID:      id,
		Token:   fmt.Sprintf("%s:%x", id, hashedSecret),
		Type:    typ,
		Created: time.Now(),
	}

	value, err := json.Marshal(token)
	if err != nil {
		return nil, err
	}
	cs.DB.Set(key, value)

	return token, nil
}

// Check returns whether or not an id-secret pair is a valid access token.
func (cs *CredentialStore) Check(ctx context.Context, id string, secret string) (bool, error) {
	if !validIDRegexp.MatchString(id) {
		return false, errors.WithDetailf(ErrBadID, "invalid id %q", id)
	}

	var value []byte
	token := &Token{}

	if value = cs.DB.Get([]byte(id)); value == nil {
		return false, errors.WithDetailf(ErrNoMatchID, "check id %q nonexisting", id)
	}
	if err := json.Unmarshal(value, token); err != nil {
		return false, err
	}

	if strings.Compare(strings.Split(token.Token, ":")[1], secret) == 0 {
		return true, nil
	}

	return false, ErrInvalidToken
}

// List lists all access tokens.
func (cs *CredentialStore) List(ctx context.Context) ([]*Token, error) {
	tokens := make([]*Token, 0)
	iter := cs.DB.Iterator()
	defer iter.Release()

	for iter.Next() {
		token := &Token{}
		if err := json.Unmarshal(iter.Value(), token); err != nil {
			return nil, err
		}
		tokens = append(tokens, token)
	}
	return tokens, nil
}

// Delete deletes an access token by id.
func (cs *CredentialStore) Delete(ctx context.Context, id string) error {
	if !validIDRegexp.MatchString(id) {
		return errors.WithDetailf(ErrBadID, "invalid id %q", id)
	}

	if value := cs.DB.Get([]byte(id)); value == nil {
		return errors.WithDetailf(ErrNoMatchID, "check id %q", id)
	}

	cs.DB.Delete([]byte(id))
	return nil
}
<|endoftext|>


<commit_before>package bettermail

import (
	"bytes"
	"fmt"
	"html"
	"sort"
	"strings"
	"time"

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

	"golang.org/x/net/context"

	"google.golang.org/appengine/log"
	"google.golang.org/appengine/urlfetch"
)

func safeFormattedDate(date string) string {
	// Insert zero-width spaces every few characters so that Apple Data
	// Detectors and Gmail's calendar event dection don't pick up on these
	// dates.
	var buffer bytes.Buffer
	dateLength := len(date)
	for i := 0; i < dateLength; i += 2 {
		if i == dateLength-1 {
			buffer.WriteString(date[i : i+1])
		} else {
			buffer.WriteString(date[i : i+2])
			if date[i] != ' ' && date[i+1] != ' ' && i < dateLength-2 {
				buffer.WriteString("\u200b")
			}
		}
	}
	return buffer.String()
}

type DisplayCommitFileType int

const (
	CommitFileAdded DisplayCommitFileType = iota
	CommitFileRemoved
	CommitFileModified
)

func (t DisplayCommitFileType) Style() string {
	var style string
	if t == CommitFileAdded {
		style = "added"
	} else if t == CommitFileRemoved {
		style = "removed"
	} else if t == CommitFileModified {
		style = "modified"
	} else {
		style = "unknown"
	}
	return fmt.Sprintf("commit.files.file.type.%s", style)
}

func (t DisplayCommitFileType) Letter() string {
	if t == CommitFileAdded {
		return "+"
	}
	if t == CommitFileRemoved {
		return "-"
	}
	if t == CommitFileModified {
		return "•"
	}
	return "?"
}

type DisplayCommitFile struct {
	Path string
	Type DisplayCommitFileType
	URL  string
}

type DisplayCommitFileByPath []DisplayCommitFile

func (a DisplayCommitFileByPath) Len() int           { return len(a) }
func (a DisplayCommitFileByPath) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a DisplayCommitFileByPath) Less(i, j int) bool { return a[i].Path < a[j].Path }

type DisplayCommiter struct {
	Login     string
	Name      string
	AvatarURL string
}

type DisplayCommit struct {
	SHA         string
	ShortSHA    string
	URL         string
	Title       string
	MessageHTML string
	Date        time.Time
	Commiter    DisplayCommiter
	Files       []DisplayCommitFile
}

const (
	DisplayDateFormat     = "3:04pm"
	DisplayDateFullFormat = "Monday January 2 3:04pm"
)

func getTitleAndMessageFromCommitMessage(message string) (string, string) {
	messagePieces := strings.SplitN(message, "\n", 2)
	title := messagePieces[0]
	if len(messagePieces) == 2 {
		message = messagePieces[1]
	}
	// Mimic title turncation done by the GitHub web UI
	if len(title) > 80 {
		titleTail := "…" + title[80:]
		if len(message) > 0 {
			message = titleTail + "\n" + message
		} else {
			message = titleTail
		}
		title = title[:80] + "…"
	}
	return title, message
}

func renderMessageMarkdown(message string, repo *WebHookRepository, c context.Context) string {
	// The Markdown endpoint does not escape <, >, etc. so we need to do it
	// ourselves.
	messageHtml := html.EscapeString(message)
	client := github.NewClient(urlfetch.Client(c))
	messageHtmlRendered, _, err := client.Markdown(messageHtml, &github.MarkdownOptions{
		Mode:    "gfm",
		Context: *repo.FullName,
	})
	if err != nil {
		log.Warningf(c, "Could not do markdown rendering, got error %s", err)
		messageHtml = fmt.Sprintf("
%s
",
			getStyle("commit.message.block"), messageHtml)
	} else {
		// Use our link style
		messageHtmlRendered = strings.Replace(
			messageHtmlRendered,
			"<a ",
			fmt.Sprintf("<a style=\"%s\" ", getStyle("link")),
			-1)
		// Respect whitespace within blocks...
		messageHtmlRendered = strings.Replace(
			messageHtmlRendered,
			"
",
			fmt.Sprintf("
", getStyle("commit.message.block")),
			-1)
		messageHtmlRendered = strings.Replace(
			messageHtmlRendered,
			"
",
			fmt.Sprintf("
", getStyle("commit.message.block")),
			-1)
		// ...but avoid doubling of newlines.
		messageHtmlRendered = strings.Replace(
			messageHtmlRendered,
			"
\n",
			"
",
			-1)
		messageHtml = messageHtmlRendered
	}
	return messageHtml
}

func newDisplayCommit(commit *WebHookCommit, sender *github.User, repo *WebHookRepository, location *time.Location, c context.Context) DisplayCommit {
	title, message := getTitleAndMessageFromCommitMessage(*commit.Message)
	messageHtml := ""
	if len(message) > 0 {
		messageHtml = renderMessageMarkdown(message, repo, c)
	}

	files := make([]DisplayCommitFile, 0)
	for _, path := range commit.Added {
		files = append(files, DisplayCommitFile{Path: path, Type: CommitFileAdded})
	}
	for _, path := range commit.Removed {
		files = append(files, DisplayCommitFile{Path: path, Type: CommitFileRemoved})
	}
	for _, path := range commit.Modified {
		files = append(files, DisplayCommitFile{Path: path, Type: CommitFileModified})
	}
	sort.Sort(DisplayCommitFileByPath(files))
	for i := range files {
		files[i].URL = fmt.Sprintf("%s#diff-%d", *commit.URL, i)
	}

	commiter := DisplayCommiter{
		Login:     *commit.Author.Username,
		Name:      *commit.Author.Name,
		AvatarURL: fmt.Sprintf("https://github.com/identicons/%s.png", *commit.Author.Username),
	}
	if sender.Login != nil && commiter.Login == *sender.Login && sender.AvatarURL != nil {
		commiter.AvatarURL = *sender.AvatarURL
	}

	return DisplayCommit{
		SHA:         *commit.ID,
		ShortSHA:    (*commit.ID)[:7],
		URL:         *commit.URL,
		Title:       title,
		MessageHTML: messageHtml,
		Date:        commit.Timestamp.In(location),
		Commiter:    commiter,
		Files:       files,
	}
}

func (commit DisplayCommit) DisplayDate() string {
	return safeFormattedDate(commit.Date.Format(DisplayDateFormat))
}

func (commit DisplayCommit) DisplayDateTooltip() string {
	return commit.Date.Format(DisplayDateFullFormat)
}
<commit_msg>Fix subject getting duplicated in message body for one-line commit messages.<commit_after>package bettermail

import (
	"bytes"
	"fmt"
	"html"
	"sort"
	"strings"
	"time"

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

	"golang.org/x/net/context"

	"google.golang.org/appengine/log"
	"google.golang.org/appengine/urlfetch"
)

func safeFormattedDate(date string) string {
	// Insert zero-width spaces every few characters so that Apple Data
	// Detectors and Gmail's calendar event dection don't pick up on these
	// dates.
	var buffer bytes.Buffer
	dateLength := len(date)
	for i := 0; i < dateLength; i += 2 {
		if i == dateLength-1 {
			buffer.WriteString(date[i : i+1])
		} else {
			buffer.WriteString(date[i : i+2])
			if date[i] != ' ' && date[i+1] != ' ' && i < dateLength-2 {
				buffer.WriteString("\u200b")
			}
		}
	}
	return buffer.String()
}

type DisplayCommitFileType int

const (
	CommitFileAdded DisplayCommitFileType = iota
	CommitFileRemoved
	CommitFileModified
)

func (t DisplayCommitFileType) Style() string {
	var style string
	if t == CommitFileAdded {
		style = "added"
	} else if t == CommitFileRemoved {
		style = "removed"
	} else if t == CommitFileModified {
		style = "modified"
	} else {
		style = "unknown"
	}
	return fmt.Sprintf("commit.files.file.type.%s", style)
}

func (t DisplayCommitFileType) Letter() string {
	if t == CommitFileAdded {
		return "+"
	}
	if t == CommitFileRemoved {
		return "-"
	}
	if t == CommitFileModified {
		return "•"
	}
	return "?"
}

type DisplayCommitFile struct {
	Path string
	Type DisplayCommitFileType
	URL  string
}

type DisplayCommitFileByPath []DisplayCommitFile

func (a DisplayCommitFileByPath) Len() int           { return len(a) }
func (a DisplayCommitFileByPath) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a DisplayCommitFileByPath) Less(i, j int) bool { return a[i].Path < a[j].Path }

type DisplayCommiter struct {
	Login     string
	Name      string
	AvatarURL string
}

type DisplayCommit struct {
	SHA         string
	ShortSHA    string
	URL         string
	Title       string
	MessageHTML string
	Date        time.Time
	Commiter    DisplayCommiter
	Files       []DisplayCommitFile
}

const (
	DisplayDateFormat     = "3:04pm"
	DisplayDateFullFormat = "Monday January 2 3:04pm"
)

func getTitleAndMessageFromCommitMessage(message string) (string, string) {
	messagePieces := strings.SplitN(message, "\n", 2)
	title := messagePieces[0]
	message = ""
	if len(messagePieces) == 2 {
		message = messagePieces[1]
	}
	// Mimic title turncation done by the GitHub web UI
	if len(title) > 80 {
		titleTail := "…" + title[80:]
		if len(message) > 0 {
			message = titleTail + "\n" + message
		} else {
			message = titleTail
		}
		title = title[:80] + "…"
	}
	return title, message
}

func renderMessageMarkdown(message string, repo *WebHookRepository, c context.Context) string {
	// The Markdown endpoint does not escape <, >, etc. so we need to do it
	// ourselves.
	messageHtml := html.EscapeString(message)
	client := github.NewClient(urlfetch.Client(c))
	messageHtmlRendered, _, err := client.Markdown(messageHtml, &github.MarkdownOptions{
		Mode:    "gfm",
		Context: *repo.FullName,
	})
	if err != nil {
		log.Warningf(c, "Could not do markdown rendering, got error %s", err)
		messageHtml = fmt.Sprintf("
%s
",
			getStyle("commit.message.block"), messageHtml)
	} else {
		// Use our link style
		messageHtmlRendered = strings.Replace(
			messageHtmlRendered,
			"<a ",
			fmt.Sprintf("<a style=\"%s\" ", getStyle("link")),
			-1)
		// Respect whitespace within blocks...
		messageHtmlRendered = strings.Replace(
			messageHtmlRendered,
			"
",
			fmt.Sprintf("
", getStyle("commit.message.block")),
			-1)
		messageHtmlRendered = strings.Replace(
			messageHtmlRendered,
			"
",
			fmt.Sprintf("
", getStyle("commit.message.block")),
			-1)
		// ...but avoid doubling of newlines.
		messageHtmlRendered = strings.Replace(
			messageHtmlRendered,
			"
\n",
			"
",
			-1)
		messageHtml = messageHtmlRendered
	}
	return messageHtml
}

func newDisplayCommit(commit *WebHookCommit, sender *github.User, repo *WebHookRepository, location *time.Location, c context.Context) DisplayCommit {
	title, message := getTitleAndMessageFromCommitMessage(*commit.Message)
	messageHtml := ""
	if len(message) > 0 {
		messageHtml = renderMessageMarkdown(message, repo, c)
	}

	files := make([]DisplayCommitFile, 0)
	for _, path := range commit.Added {
		files = append(files, DisplayCommitFile{Path: path, Type: CommitFileAdded})
	}
	for _, path := range commit.Removed {
		files = append(files, DisplayCommitFile{Path: path, Type: CommitFileRemoved})
	}
	for _, path := range commit.Modified {
		files = append(files, DisplayCommitFile{Path: path, Type: CommitFileModified})
	}
	sort.Sort(DisplayCommitFileByPath(files))
	for i := range files {
		files[i].URL = fmt.Sprintf("%s#diff-%d", *commit.URL, i)
	}

	commiter := DisplayCommiter{
		Login:     *commit.Author.Username,
		Name:      *commit.Author.Name,
		AvatarURL: fmt.Sprintf("https://github.com/identicons/%s.png", *commit.Author.Username),
	}
	if sender.Login != nil && commiter.Login == *sender.Login && sender.AvatarURL != nil {
		commiter.AvatarURL = *sender.AvatarURL
	}

	return DisplayCommit{
		SHA:         *commit.ID,
		ShortSHA:    (*commit.ID)[:7],
		URL:         *commit.URL,
		Title:       title,
		MessageHTML: messageHtml,
		Date:        commit.Timestamp.In(location),
		Commiter:    commiter,
		Files:       files,
	}
}

func (commit DisplayCommit) DisplayDate() string {
	return safeFormattedDate(commit.Date.Format(DisplayDateFormat))
}

func (commit DisplayCommit) DisplayDateTooltip() string {
	return commit.Date.Format(DisplayDateFullFormat)
}
<|endoftext|>


<commit_before><commit_msg>flowcontrol bootstrap: give catch-all PL more concurrency share<commit_after><|endoftext|>


<commit_before>package fsd

import (
	"errors"
	"fmt"
	"math/rand"
	"net"
	"strconv"
	"time"
)

var (
	Instance *Fsd
)

type Fsd struct {
	outgoing chan string
	address  string
	conn     net.Conn
}

func init() {
	Start("127.0.0.1:8125")
}

func Start(address string) {
	Instance = &Fsd{address: address, outgoing: make(chan string, 100000)}
	Instance.connect()

	go Instance.processOutgoing()
}

func (fsd *Fsd) connect() error {
	conn, err := net.Dial("udp", fsd.address)
	if err != nil {
		return err
	}

	fsd.conn = conn
	return nil
}

func (fsd *Fsd) processOutgoing() {
	for outgoing := range fsd.outgoing {
		if _, err := fsd.conn.Write([]byte(outgoing)); err != nil {
			fsd.connect()
		}
	}
}

// To read about the different semantics check out
// https://github.com/b/statsd_spec
// http://docs.datadoghq.com/guides/dogstatsd/

// Increment the page.views counter.
// page.views:1|c
func Count(name string, value float64) {
	CountL(name, value, 1.0)
}

func CountL(name string, value float64, rate float64) {
	payload, err := rateCheck(rate, createPayload(name, value, "c"))
	if err != nil {
		return
	}

	send(payload)
}

// Record the fuel tank is half-empty
// fuel.level:0.5|g
func Gauge(name string, value float64) {
	payload := createPayload(name, value, "g")
	send(payload)
}

// A request latency
// request.latency:320|ms
// Or a payload of a image
// image.size:2.3|ms
func Timer(name string, duration time.Duration) {
	TimerL(name, duration, 1.0)
}

func TimerL(name string, duration time.Duration, rate float64) {
	HistogramL(name, float64(duration.Nanoseconds()/1000000), rate)
}

func Histogram(name string, value float64) {
	HistogramL(name, value, 1.0)
}

func HistogramL(name string, value float64, rate float64) {
	payload, err := rateCheck(rate, createPayload(name, value, "ms"))
	if err != nil {
		return
	}

	send(payload)
}

// TimeSince records a named timer with the duration since start
func TimeSince(name string, start time.Time) {
	TimeSinceL(name, start, 1.0)
}

// TimeSince records a rated and named timer with the duration since start
func TimeSinceL(name string, start time.Time, rate float64) {
	TimerL(name, time.Now().Sub(start), rate)
}

func Time(name string, lambda func()) {
	TimeL(name, 1.0, lambda)
}

func TimeL(name string, rate float64, lambda func()) {
	start := time.Now()
	lambda()
	TimeSinceL(name, start, rate)
}

// Track a unique visitor id to the site.
// users.uniques:1234|s
func Set(name string, value float64) {
	payload := createPayload(name, value, "s")
	send(payload)
}

func createPayload(name string, value float64, suffix string) string {
	// we spend a lot of time in this code
	return name + ":" + strconv.FormatFloat(value, 'f', -1, 64) + "|" + suffix
	//return fmt.Sprintf("%s:%f|%s", name, value, suffix)
}

func rateCheck(rate float64, payload string) (string, error) {
	if rate < 1 {
		if rand.Float64() < rate {
			return payload + fmt.Sprintf("|@%f", rate), nil
		}
	} else { // rate is 1.0 == all samples should be sent
		return payload, nil
	}

	return "", errors.New("Out of rate limit")
}

func send(payload string) {
	length := float64(len(Instance.outgoing))
	capacity := float64(cap(Instance.outgoing))

	if length < capacity*0.9 {
		Instance.outgoing <- payload
	}
}
<commit_msg>Specify custom statsd address via flag<commit_after>// Package fsd is a client library for accessing StatsD daemon. You can specify
// custom StatsD port via statsd flag
package fsd

import (
	"errors"
	"flag"
	"fmt"
	"math/rand"
	"net"
	"strconv"
	"time"
)

var (
	Instance *Fsd
	address  *string = flag.String("statsd", "127.0.0.1:8125", "UDP endpoint for StatsD daemon")
)

type Fsd struct {
	outgoing chan string
	conn     net.Conn
}

func init() {
	start()
}

func start() {
	Instance = &Fsd{outgoing: make(chan string, 100000)}
	Instance.connect()

	go Instance.processOutgoing()
}

func (fsd *Fsd) connect() error {
	conn, err := net.Dial("udp", *address)
	if err != nil {
		return err
	}

	fsd.conn = conn
	return nil
}

func (fsd *Fsd) processOutgoing() {
	for outgoing := range fsd.outgoing {
		if _, err := fsd.conn.Write([]byte(outgoing)); err != nil {
			fsd.connect()
		}
	}
}

// To read about the different semantics check out
// https://github.com/b/statsd_spec
// http://docs.datadoghq.com/guides/dogstatsd/

// Increment the page.views counter.
// page.views:1|c
func Count(name string, value float64) {
	CountL(name, value, 1.0)
}

func CountL(name string, value float64, rate float64) {
	payload, err := rateCheck(rate, createPayload(name, value, "c"))
	if err != nil {
		return
	}

	send(payload)
}

// Record the fuel tank is half-empty
// fuel.level:0.5|g
func Gauge(name string, value float64) {
	payload := createPayload(name, value, "g")
	send(payload)
}

// A request latency
// request.latency:320|ms
// Or a payload of a image
// image.size:2.3|ms
func Timer(name string, duration time.Duration) {
	TimerL(name, duration, 1.0)
}

func TimerL(name string, duration time.Duration, rate float64) {
	HistogramL(name, float64(duration.Nanoseconds()/1000000), rate)
}

func Histogram(name string, value float64) {
	HistogramL(name, value, 1.0)
}

func HistogramL(name string, value float64, rate float64) {
	payload, err := rateCheck(rate, createPayload(name, value, "ms"))
	if err != nil {
		return
	}

	send(payload)
}

// TimeSince records a named timer with the duration since start
func TimeSince(name string, start time.Time) {
	TimeSinceL(name, start, 1.0)
}

// TimeSince records a rated and named timer with the duration since start
func TimeSinceL(name string, start time.Time, rate float64) {
	TimerL(name, time.Now().Sub(start), rate)
}

func Time(name string, lambda func()) {
	TimeL(name, 1.0, lambda)
}

func TimeL(name string, rate float64, lambda func()) {
	start := time.Now()
	lambda()
	TimeSinceL(name, start, rate)
}

// Track a unique visitor id to the site.
// users.uniques:1234|s
func Set(name string, value float64) {
	payload := createPayload(name, value, "s")
	send(payload)
}

func createPayload(name string, value float64, suffix string) string {
	// we spend a lot of time in this code
	return name + ":" + strconv.FormatFloat(value, 'f', -1, 64) + "|" + suffix
	//return fmt.Sprintf("%s:%f|%s", name, value, suffix)
}

func rateCheck(rate float64, payload string) (string, error) {
	if rate < 1 {
		if rand.Float64() < rate {
			return payload + fmt.Sprintf("|@%f", rate), nil
		}
	} else { // rate is 1.0 == all samples should be sent
		return payload, nil
	}

	return "", errors.New("Out of rate limit")
}

func send(payload string) {
	length := float64(len(Instance.outgoing))
	capacity := float64(cap(Instance.outgoing))

	if length < capacity*0.9 {
		Instance.outgoing <- payload
	}
}
<|endoftext|>


<commit_before>// Provide test server for angular ui
package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"path"
	"strconv"
	"time"
)

func main() {
	if len(os.Args) != 3 {
		fmt.Printf("%s <port> <path>\n", os.Args[0])
		os.Exit(1)
	}
	_, err := strconv.Atoi(os.Args[1])
	if err != nil {
		fmt.Printf("port: \"%s\" not a valid number\n", os.Args[1])
		os.Exit(1)
	}
	datapath := os.Args[2]
	muxer := http.NewServeMux()
	muxer.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("===== Call begin =====")
		fmt.Printf("%s %s\n", r.Method, r.URL)
		fmt.Println("Headers:")
		for k, v := range r.Header {
			fmt.Printf("    %s: %s\n", k, v)
		}
		if r.Method == "GET" {
			// Return file from path
			urlParsed, _ := url.ParseRequestURI(r.RequestURI)
			if urlParsed.Path == "" || urlParsed.Path == "/" {
				urlParsed.Path = "index.html"
			}
			filename := path.Join(datapath, urlParsed.Path)
			content, err := ioutil.ReadFile(filename)
			if err != nil {
				fmt.Printf("\"%s\": %s\n", filename, err)
				w.Write([]byte("{ \"status\": \"error\" }"))
			} else {
				fmt.Printf("Serving: \"%s\"\n", filename)
				w.Write(content)
			}
		} else {
			// Print
			if r.ContentLength > 0 {
				body := make([]byte, r.ContentLength)
				io.ReadFull(r.Body, body)
				fmt.Printf("===== Body begin =====\n%s\n===== Body end =====\n", body)
			}
			w.Write([]byte("{ \"status\": \"ok\" }"))
		}
		fmt.Println("===== Call end =====\n\n\n")
	})
	s := &http.Server{
		Addr:           ":" + os.Args[1],
		Handler:        muxer,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	log.Fatal(s.ListenAndServe())
}
<commit_msg>add missing copyright header<commit_after>// Copyright (c) 2016 Mute Communications Ltd.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Provide test server for angular ui
package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"path"
	"strconv"
	"time"
)

func main() {
	if len(os.Args) != 3 {
		fmt.Printf("%s <port> <path>\n", os.Args[0])
		os.Exit(1)
	}
	_, err := strconv.Atoi(os.Args[1])
	if err != nil {
		fmt.Printf("port: \"%s\" not a valid number\n", os.Args[1])
		os.Exit(1)
	}
	datapath := os.Args[2]
	muxer := http.NewServeMux()
	muxer.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("===== Call begin =====")
		fmt.Printf("%s %s\n", r.Method, r.URL)
		fmt.Println("Headers:")
		for k, v := range r.Header {
			fmt.Printf("    %s: %s\n", k, v)
		}
		if r.Method == "GET" {
			// Return file from path
			urlParsed, _ := url.ParseRequestURI(r.RequestURI)
			if urlParsed.Path == "" || urlParsed.Path == "/" {
				urlParsed.Path = "index.html"
			}
			filename := path.Join(datapath, urlParsed.Path)
			content, err := ioutil.ReadFile(filename)
			if err != nil {
				fmt.Printf("\"%s\": %s\n", filename, err)
				w.Write([]byte("{ \"status\": \"error\" }"))
			} else {
				fmt.Printf("Serving: \"%s\"\n", filename)
				w.Write(content)
			}
		} else {
			// Print
			if r.ContentLength > 0 {
				body := make([]byte, r.ContentLength)
				io.ReadFull(r.Body, body)
				fmt.Printf("===== Body begin =====\n%s\n===== Body end =====\n", body)
			}
			w.Write([]byte("{ \"status\": \"ok\" }"))
		}
		fmt.Println("===== Call end =====\n\n\n")
	})
	s := &http.Server{
		Addr:           ":" + os.Args[1],
		Handler:        muxer,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	log.Fatal(s.ListenAndServe())
}
<|endoftext|>


<commit_before>package titan

import (
    "time"
)

type Job struct {
    Image  string  `json:"image,omitempty"`
    CreatedAt  time.Time  `json:"created_at,omitempty"`
    Priority  int32  `json:"priority,omitempty"`
    RetriesDelay  int32  `json:"retries_delay,omitempty"`
    Error  string  `json:"error,omitempty"`
    Timeout  int32  `json:"timeout,omitempty"`
    Retries  int32  `json:"retries,omitempty"`
    CompletedAt  time.Time  `json:"completed_at,omitempty"`
    Delay  int32  `json:"delay,omitempty"`
    Payload  string  `json:"payload,omitempty"`
    Name  string  `json:"name,omitempty"`
    StartedAt  time.Time  `json:"started_at,omitempty"`
    Id  string  `json:"id,omitempty"`
    RetryId  string  `json:"retry_id,omitempty"`
    Status  string  `json:"status,omitempty"`

}
<commit_msg>Updated to api version 0.0.7<commit_after>package titan

import (
    "time"
)

type Job struct {
    Image  string  `json:"image,omitempty"`
    RetryFromId  string  `json:"retry_from_id,omitempty"`
    CreatedAt  time.Time  `json:"created_at,omitempty"`
    Priority  int32  `json:"priority,omitempty"`
    RetriesDelay  int32  `json:"retries_delay,omitempty"`
    Error  string  `json:"error,omitempty"`
    Timeout  int32  `json:"timeout,omitempty"`
    Retries  int32  `json:"retries,omitempty"`
    CompletedAt  time.Time  `json:"completed_at,omitempty"`
    Delay  int32  `json:"delay,omitempty"`
    Payload  string  `json:"payload,omitempty"`
    Name  string  `json:"name,omitempty"`
    StartedAt  time.Time  `json:"started_at,omitempty"`
    Id  string  `json:"id,omitempty"`
    RetryId  string  `json:"retry_id,omitempty"`
    Status  string  `json:"status,omitempty"`

}
<|endoftext|>