<commit_before>// Package wbzr provides tool to create a wooble in a given language and to package
// (wrap) some woobles.
package wbzr

import (
	"errors"
	"io"
	"io/ioutil"
	"os"
	"text/template"

	"github.com/woobleio/wooblizer/wbzr/engine"
)

// ScriptLang are constants for implemented script languages.
type ScriptLang int

const (
	JSES5 ScriptLang = iota
)

type wbzr struct {
	ext      string
	lang     ScriptLang
	scripts  []engine.Script
	skeleton string
}

// New takes a script language which is used to inject and output a file.
func New(sl ScriptLang) *wbzr {
	var skeleton, ext string
	switch sl {
	case JSES5:
		skeleton = wbJses5
		ext = ".min.js"
	default:
		panic("Language not supported")
	}

	return &wbzr{
		ext,
		sl,
		make([]engine.Script, 0),
		skeleton,
	}
}

// BuildScriptFile make a wooble. The parameter wbName is the name of the injected source
// you want to build
func (wb *wbzr) BuildScriptFile(wbName string, path string, fileName string) error {
	script, err := wb.Get(wbName)
	if err != nil {
		return err
	}

	tmplSrc, err := script.Build()
	if err != nil {
		return err
	}

	f, err := os.Create(path + "/" + fileName + wb.ext)
	if err != nil {
		return err
	}
	defer f.Close()

	if err := tmplSrc.Execute(f, script); err != nil {
		return err
	}

	return nil
}

// Get returns an injected source.
func (wb *wbzr) Get(name string) (engine.Script, error) {
	for _, sc := range wb.scripts {
		if sc.GetName() == name {
			return sc, nil
		}
	}
	return nil, errors.New("Wooble " + name + " not found")
}

// Inject injects a source code to be wooblized. It takes a name which must be
// unique. Src can be empty, it'll create a default object
func (wb *wbzr) Inject(src string, name string) (engine.Script, error) {
	if _, err := wb.Get(name); err == nil {
		return nil, errors.New("Wooble " + name + " already exists. A name must be unique")
	}
	var sc engine.Script
	switch wb.lang {
	case JSES5:
		sc, err := engine.NewJSES5(src, name)
		if err != nil {
			return nil, err
		}
		wb.scripts = append(wb.scripts, sc)
	}
	return sc, nil
}

// InjectFile injects a source from a file.
func (wb *wbzr) InjectFile(path string, name string) (engine.Script, error) {
	c, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	return wb.Inject(string(c[:]), name)
}

// Wrap packages some woobles (all the woobles injected in the wbzr)
// and build a file which contains the wooble library.
func (wb *wbzr) Wrap() (*io.Writer, error) {
	for _, sc := range wb.scripts {
		if _, err := sc.Build(); err != nil {
			return nil, err
		}
	}

	tmpl := template.Must(template.New("WbJSES5").Parse(wbJses5))

	var writer io.Writer
	if err := tmpl.Execute(writer, wb.scripts); err != nil {
		return nil, err
	}

	return &writer, nil
}

var wbJses5 = `
function Wb(id) {
	if(window === this) {
  	return new Wb(id);
  }

  var cs = {
  	{{range $i, $o := .}}"{{$o.GetName}}":{{"{"}}{{$o.GetSource}}{{"}"}}{{if not $i}},{{end}}{{end}}
  }

  var c = cs[id];
  if(typeof c == 'undefined') {
  	console.log("creation", id, "not found");
    return undefined;
  }

  this.init = function (target) {
    if(document.querySelector(target) == null) {
    	console.log("Element", target, "not found in the document");
      return;
    }

    if("_buildDoc" in c) c._buildDoc(target);
    if("_buildStyle" in c) c._buildStyle();
    if("_init" in c) c._init();
  }

  this.get = function() {
  	return c;
  }

  return this;
}
`
<commit_msg>Changes Wrap return to *bytes.Buffer<commit_after>// Package wbzr provides tool to create a wooble in a given language and to package
// (wrap) some woobles.
package wbzr

import (
	"bytes"
	"errors"
	"io/ioutil"
	"os"
	"text/template"

	"github.com/woobleio/wooblizer/wbzr/engine"
)

// ScriptLang are constants for implemented script languages.
type ScriptLang int

const (
	JSES5 ScriptLang = iota
)

type wbzr struct {
	ext      string
	lang     ScriptLang
	scripts  []engine.Script
	skeleton string
}

// New takes a script language which is used to inject and output a file.
func New(sl ScriptLang) *wbzr {
	var skeleton, ext string
	switch sl {
	case JSES5:
		skeleton = wbJses5
		ext = ".min.js"
	default:
		panic("Language not supported")
	}

	return &wbzr{
		ext,
		sl,
		make([]engine.Script, 0),
		skeleton,
	}
}

// BuildScriptFile make a wooble. The parameter wbName is the name of the injected source
// you want to build
func (wb *wbzr) BuildScriptFile(wbName string, path string, fileName string) error {
	script, err := wb.Get(wbName)
	if err != nil {
		return err
	}

	tmplSrc, err := script.Build()
	if err != nil {
		return err
	}

	f, err := os.Create(path + "/" + fileName + wb.ext)
	if err != nil {
		return err
	}
	defer f.Close()

	if err := tmplSrc.Execute(f, script); err != nil {
		return err
	}

	return nil
}

// Get returns an injected source.
func (wb *wbzr) Get(name string) (engine.Script, error) {
	for _, sc := range wb.scripts {
		if sc.GetName() == name {
			return sc, nil
		}
	}
	return nil, errors.New("Wooble " + name + " not found")
}

// Inject injects a source code to be wooblized. It takes a name which must be
// unique. Src can be empty, it'll create a default object
func (wb *wbzr) Inject(src string, name string) (engine.Script, error) {
	if _, err := wb.Get(name); err == nil {
		return nil, errors.New("Wooble " + name + " already exists. A name must be unique")
	}
	var sc engine.Script
	switch wb.lang {
	case JSES5:
		sc, err := engine.NewJSES5(src, name)
		if err != nil {
			return nil, err
		}
		wb.scripts = append(wb.scripts, sc)
	}
	return sc, nil
}

// InjectFile injects a source from a file.
func (wb *wbzr) InjectFile(path string, name string) (engine.Script, error) {
	c, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	return wb.Inject(string(c[:]), name)
}

// Wrap packages some woobles (all the woobles injected in the wbzr)
// and build a file which contains the wooble library.
func (wb *wbzr) Wrap() (*bytes.Buffer, error) {
	for _, sc := range wb.scripts {
		if _, err := sc.Build(); err != nil {
			return nil, err
		}
	}

	tmpl := template.Must(template.New("WbJSES5").Parse(wbJses5))

	var out bytes.Buffer
	if err := tmpl.Execute(&out, wb.scripts); err != nil {
		return nil, err
	}

	return &out, nil
}

var wbJses5 = `
function Wb(id) {
	if(window === this) {
  	return new Wb(id);
  }

  var cs = {
  	{{range $i, $o := .}}"{{$o.GetName}}":{{"{"}}{{$o.GetSource}}{{"}"}}{{if not $i}},{{end}}{{end}}
  }

  var c = cs[id];
  if(typeof c == 'undefined') {
  	console.log("creation", id, "not found");
    return undefined;
  }

  this.init = function (target) {
    if(document.querySelector(target) == null) {
    	console.log("Element", target, "not found in the document");
      return;
    }

    if("_buildDoc" in c) c._buildDoc(target);
    if("_buildStyle" in c) c._buildStyle();
    if("_init" in c) c._init();
  }

  this.get = function() {
  	return c;
  }

  return this;
}
`
<|endoftext|>


<commit_before>package usecases

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/webitel/cdr/src/conf"
	"github.com/webitel/cdr/src/entity"
	"github.com/webitel/cdr/src/logger"
)

func (interactor *CdrInteractor) RunAccounts() {
	if interactor.AmqAccountRepository == nil {
		return
	}
	publisher := conf.GetAccountPublisher()
	if publisher.Enable == false {
		return
	}
	size, interval := conf.GetAccountConfig()
	for {
		var done = make(chan error)
		interactor.AmqAccountRepository.CreateAmqConnection(publisher.ConnectionString, publisher.ExchangeName, publisher.ExchangeType)
		if err := interactor.AmqAccountRepository.InitExchange(publisher.ExchangeType, publisher.ExchangeName); err != nil {
			logger.Error(err.Error())
			continue
		}
		msgs, err := interactor.AmqAccountRepository.GetMessages(publisher.ExchangeName, publisher.ExchangeType, publisher.RoutingKey)
		if err != nil {
			logger.Error(err.Error())
			continue
		}
		go interactor.ListenStatus(msgs, size, interval, done)
		logger.Log("RabbitMQ: start listening accounts...")
		err = <-done
		logger.Error(err.Error())
	}
}

func (interactor *CdrInteractor) ListenStatus(msgs <-chan entity.Delivery, size, interval uint32, done chan error) {
	batch := make([]entity.Delivery, 0, size)
	promise := time.Millisecond * time.Duration(interval)
	tmr := time.NewTimer(promise)
	for {
		select {
		case <-tmr.C:
			{
				if len(batch) > 0 {
					go interactor.AccountProcess(batch)
					batch = make([]entity.Delivery, 0, size)
				}
				tmr.Reset(promise)
			}
		case d, ok := <-msgs:
			{
				if !ok {
					if len(batch) > 0 && len(batch) != cap(batch) {
						go interactor.AccountProcess(batch)
					}
					done <- fmt.Errorf("RabbitMQ: Deliveries channel closed [ACCOUNTS]")
					return
				}
				batch = append(batch, d)
				if len(batch) == cap(batch) {
					go interactor.AccountProcess(batch)
					batch = make([]entity.Delivery, 0, size)
					tmr.Reset(promise)
				}
			}
		}
	}
}

func (interactor *CdrInteractor) AccountProcess(batch []entity.Delivery) {
	if err, dResponse := interactor.AccountSend(batch); err != nil {
		if dResponse != nil && len(dResponse) > 0 {
			successCounter, errorCounter := 0, 0
			for i, _ := range dResponse {
				if dResponse[i].Success {
					successCounter++
					dResponse[i].Delivery.Ack(false)
				} else {
					errorCounter++
					dResponse[i].Delivery.Nack(false, true)
				}
			}
			logger.Info("Elastic: items stored [Accounts, %v]", successCounter)
			logger.Warning("Elastic: failed to store items [Accounts, %v]", errorCounter)
		} else {
			for i := 0; i < len(batch); i++ {
				batch[i].Nack(false, true)
			}
			logger.Error(err.Error())
			logger.Warning("Elastic: failed to store items [Accounts, %v]", len(batch))
		}
	} else {
		for i := 0; i < len(batch); i++ {
			batch[i].Ack(false)
		}
		logger.Info("Elastic: items stored [Accounts, %v]", len(batch))
	}
}

func (interactor *CdrInteractor) AccountSend(batch []entity.Delivery) (error, []DeliveryResponse) {
	var accounts []entity.Account
	var deliveriesResponse []DeliveryResponse
	for _, item := range batch {
		err, acc := getAccount(item.GetBody())
		if err != nil {
			return err, nil
		}
		acc.Uuid = GenerateUuid()
		accounts = append(accounts, acc)
		deliveriesResponse = append(deliveriesResponse, DeliveryResponse{Delivery: item, Uuid: acc.Uuid})
	}
	if err, errAcc, succAcc := interactor.ElasticAccountsRepository.InsertDocs(accounts); err != nil {
		if succAcc != nil && len(errAcc) > 0 {
			for i, _ := range deliveriesResponse {
				for _, item := range succAcc {
					if deliveriesResponse[i].Uuid == item.Uuid {
						deliveriesResponse[i].Success = true
					}
				}
			}
			return err, deliveriesResponse
		} else {
			return err, nil
		}
	}
	return nil, nil
}

func getAccount(body []byte) (error, entity.Account) {
	var acc entity.Account
	if err := json.Unmarshal(body, &acc); err != nil {
		return err, acc
	}
	return nil, acc
}
<commit_msg>accounts max gr<commit_after>package usecases

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/webitel/cdr/src/conf"
	"github.com/webitel/cdr/src/entity"
	"github.com/webitel/cdr/src/logger"
)

func (interactor *CdrInteractor) RunAccounts() {
	if interactor.AmqAccountRepository == nil {
		return
	}
	publisher := conf.GetAccountPublisher()
	if publisher.Enable == false {
		return
	}
	size, interval := conf.GetAccountConfig()
	for {
		var done = make(chan error)
		interactor.AmqAccountRepository.CreateAmqConnection(publisher.ConnectionString, publisher.ExchangeName, publisher.ExchangeType)
		if err := interactor.AmqAccountRepository.InitExchange(publisher.ExchangeType, publisher.ExchangeName); err != nil {
			logger.Error(err.Error())
			continue
		}
		msgs, err := interactor.AmqAccountRepository.GetMessages(publisher.ExchangeName, publisher.ExchangeType, publisher.RoutingKey)
		if err != nil {
			logger.Error(err.Error())
			continue
		}
		go interactor.ListenStatus(msgs, size, interval, done)
		logger.Log("RabbitMQ: start listening accounts...")
		err = <-done
		logger.Error(err.Error())
	}
}

func (interactor *CdrInteractor) ListenStatus(msgs <-chan entity.Delivery, size, interval uint32, done chan error) {
	batch := make([]entity.Delivery, 0, size)
	promise := time.Millisecond * time.Duration(interval)
	tmr := time.NewTimer(promise)
	maxGr := conf.MaxGoroutines()
	sem := make(chan struct{}, maxGr)
	for {
		select {
		case <-tmr.C:
			{
				if len(batch) > 0 {
					sem <- struct{}{}
					go interactor.AccountProcess(batch, sem)
					batch = make([]entity.Delivery, 0, size)
				}
				tmr.Reset(promise)
			}
		case d, ok := <-msgs:
			{
				if !ok {
					if len(batch) > 0 && len(batch) != cap(batch) {
						sem <- struct{}{}
						go interactor.AccountProcess(batch, sem)
					}
					done <- fmt.Errorf("RabbitMQ: Deliveries channel closed [ACCOUNTS]")
					return
				}
				batch = append(batch, d)
				if len(batch) == cap(batch) {
					sem <- struct{}{}
					go interactor.AccountProcess(batch, sem)
					batch = make([]entity.Delivery, 0, size)
					tmr.Reset(promise)
				}
			}
		}
	}
}

func (interactor *CdrInteractor) AccountProcess(batch []entity.Delivery, sem chan struct{}) {
	if err, dResponse := interactor.AccountSend(batch); err != nil {
		if dResponse != nil && len(dResponse) > 0 {
			successCounter, errorCounter := 0, 0
			for i, _ := range dResponse {
				if dResponse[i].Success {
					successCounter++
					dResponse[i].Delivery.Ack(false)
				} else {
					errorCounter++
					dResponse[i].Delivery.Nack(false, true)
				}
			}
			logger.Info("Elastic: items stored [Accounts, %v]", successCounter)
			logger.Warning("Elastic: failed to store items [Accounts, %v]", errorCounter)
		} else {
			for i := 0; i < len(batch); i++ {
				batch[i].Nack(false, true)
			}
			logger.Error(err.Error())
			logger.Warning("Elastic: failed to store items [Accounts, %v]", len(batch))
		}
	} else {
		for i := 0; i < len(batch); i++ {
			batch[i].Ack(false)
		}
		logger.Info("Elastic: items stored [Accounts, %v]", len(batch))
	}
	<-sem
}

func (interactor *CdrInteractor) AccountSend(batch []entity.Delivery) (error, []DeliveryResponse) {
	var accounts []entity.Account
	var deliveriesResponse []DeliveryResponse
	for _, item := range batch {
		err, acc := getAccount(item.GetBody())
		if err != nil {
			return err, nil
		}
		acc.Uuid = GenerateUuid()
		accounts = append(accounts, acc)
		deliveriesResponse = append(deliveriesResponse, DeliveryResponse{Delivery: item, Uuid: acc.Uuid})
	}
	if err, errAcc, succAcc := interactor.ElasticAccountsRepository.InsertDocs(accounts); err != nil {
		if succAcc != nil && len(errAcc) > 0 {
			for i, _ := range deliveriesResponse {
				for _, item := range succAcc {
					if deliveriesResponse[i].Uuid == item.Uuid {
						deliveriesResponse[i].Success = true
					}
				}
			}
			return err, deliveriesResponse
		} else {
			return err, nil
		}
	}
	return nil, nil
}

func getAccount(body []byte) (error, entity.Account) {
	var acc entity.Account
	if err := json.Unmarshal(body, &acc); err != nil {
		return err, acc
	}
	return nil, acc
}
<|endoftext|>


<commit_before>package main

import (
	"unicode/utf8"
	"net/http"
	"os/exec"
	"strings"
	"errors"
	"bytes"
	"fmt"
	"log"
)

// kballard: go-shellquote

var (
	UnterminatedSingleQuoteError = errors.New("Unterminated single-quoted string")
	UnterminatedDoubleQuoteError = errors.New("Unterminated double-quoted string")
	UnterminatedEscapeError      = errors.New("Unterminated backslash-escape")
)

var (
	splitChars        = " \n\t"
	singleChar        = '\''
	doubleChar        = '"'
	escapeChar        = '\\'
	doubleEscapeChars = "$`\"\n\\"
)

func Split(input string) (words []string, err error) {
	var buf bytes.Buffer
	words = make([]string, 0)

	for len(input) > 0 {
		// skip any splitChars at the start
		c, l := utf8.DecodeRuneInString(input)
		if strings.ContainsRune(splitChars, c) {
			input = input[l:]
			continue
		}

		var word string
		word, input, err = splitWord(input, &buf)
		if err != nil {
			return
		}
		words = append(words, word)
	}
	return
}

func splitWord(input string, buf *bytes.Buffer) (word string, remainder string, err error) {
	buf.Reset()

raw:
	{
		cur := input
		for len(cur) > 0 {
			c, l := utf8.DecodeRuneInString(cur)
			cur = cur[l:]
			if c == singleChar {
				buf.WriteString(input[0 : len(input)-len(cur)-l])
				input = cur
				goto single
			} else if c == doubleChar {
				buf.WriteString(input[0 : len(input)-len(cur)-l])
				input = cur
				goto double
			} else if c == escapeChar {
				buf.WriteString(input[0 : len(input)-len(cur)-l])
				input = cur
				goto escape
			} else if strings.ContainsRune(splitChars, c) {
				buf.WriteString(input[0 : len(input)-len(cur)-l])
				return buf.String(), cur, nil
			}
		}
		if len(input) > 0 {
			buf.WriteString(input)
			input = ""
		}
		goto done
	}

escape:
	{
		if len(input) == 0 {
			return "", "", UnterminatedEscapeError
		}
		c, l := utf8.DecodeRuneInString(input)
		if c == '\n' {
		} else {
			buf.WriteString(input[:l])
		}
		input = input[l:]
	}
	goto raw

single:
	{
		i := strings.IndexRune(input, singleChar)
		if i == -1 {
			return "", "", UnterminatedSingleQuoteError
		}
		buf.WriteString(input[0:i])
		input = input[i+1:]
		goto raw
	}

double:
	{
		cur := input
		for len(cur) > 0 {
			c, l := utf8.DecodeRuneInString(cur)
			cur = cur[l:]
			if c == doubleChar {
				buf.WriteString(input[0 : len(input)-len(cur)-l])
				input = cur
				goto raw
			} else if c == escapeChar {
				c2, l2 := utf8.DecodeRuneInString(cur)
				cur = cur[l2:]
				if strings.ContainsRune(doubleEscapeChars, c2) {
					buf.WriteString(input[0 : len(input)-len(cur)-l-l2])
					if c2 == '\n' {
					} else {
						buf.WriteRune(c2)
					}
					input = cur
				}
			}
		}
		return "", "", UnterminatedDoubleQuoteError
	}

done:
	return buf.String(), input, nil
}

// go-shellquote ends here.

func run_cmd( s string ) string {

	fmt.Println("exec:", s)

	args, _ := Split( s )

	// cmd := exec.Command( s )

	cmd := exec.Command( args[0], args[1:]... )

	var out bytes.Buffer

	cmd.Stdout = &out

	err2 := cmd.Run()

	if err2 != nil {
		log.Println( err2 )
		return "error"
	}

	output_string := out.String()
	output_string = strings.Replace( output_string, "\n", "
", -1 )

	// return out.String()
	return output_string

}

func handler(w http.ResponseWriter, r *http.Request) {

	fmt.Fprintf( w, "<form method=\"post\"><input type=\"text\" name=\"c\" />
<input type=\"submit\" value=\"Ok\" /></form>" )

	if r.Method == "POST" {

		fmt.Println( r.FormValue("c") )

		input_cmd := r.FormValue("c")

		fmt.Fprintf( w, run_cmd( input_cmd )  )

	}

}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}
<commit_msg>showing stuff from stderr, larger input, and input focus on page load<commit_after>package main

import (
	"unicode/utf8"
	"net/http"
	"os/exec"
	"strings"
	"errors"
	"bytes"
	"fmt"
	"log"
)

// kballard: go-shellquote

var (
	UnterminatedSingleQuoteError = errors.New("Unterminated single-quoted string")
	UnterminatedDoubleQuoteError = errors.New("Unterminated double-quoted string")
	UnterminatedEscapeError      = errors.New("Unterminated backslash-escape")
)

var (
	splitChars        = " \n\t"
	singleChar        = '\''
	doubleChar        = '"'
	escapeChar        = '\\'
	doubleEscapeChars = "$`\"\n\\"
)

func Split(input string) (words []string, err error) {
	var buf bytes.Buffer
	words = make([]string, 0)

	for len(input) > 0 {
		// skip any splitChars at the start
		c, l := utf8.DecodeRuneInString(input)
		if strings.ContainsRune(splitChars, c) {
			input = input[l:]
			continue
		}

		var word string
		word, input, err = splitWord(input, &buf)
		if err != nil {
			return
		}
		words = append(words, word)
	}
	return
}

func splitWord(input string, buf *bytes.Buffer) (word string, remainder string, err error) {
	buf.Reset()

raw:
	{
		cur := input
		for len(cur) > 0 {
			c, l := utf8.DecodeRuneInString(cur)
			cur = cur[l:]
			if c == singleChar {
				buf.WriteString(input[0 : len(input)-len(cur)-l])
				input = cur
				goto single
			} else if c == doubleChar {
				buf.WriteString(input[0 : len(input)-len(cur)-l])
				input = cur
				goto double
			} else if c == escapeChar {
				buf.WriteString(input[0 : len(input)-len(cur)-l])
				input = cur
				goto escape
			} else if strings.ContainsRune(splitChars, c) {
				buf.WriteString(input[0 : len(input)-len(cur)-l])
				return buf.String(), cur, nil
			}
		}
		if len(input) > 0 {
			buf.WriteString(input)
			input = ""
		}
		goto done
	}

escape:
	{
		if len(input) == 0 {
			return "", "", UnterminatedEscapeError
		}
		c, l := utf8.DecodeRuneInString(input)
		if c == '\n' {
		} else {
			buf.WriteString(input[:l])
		}
		input = input[l:]
	}
	goto raw

single:
	{
		i := strings.IndexRune(input, singleChar)
		if i == -1 {
			return "", "", UnterminatedSingleQuoteError
		}
		buf.WriteString(input[0:i])
		input = input[i+1:]
		goto raw
	}

double:
	{
		cur := input
		for len(cur) > 0 {
			c, l := utf8.DecodeRuneInString(cur)
			cur = cur[l:]
			if c == doubleChar {
				buf.WriteString(input[0 : len(input)-len(cur)-l])
				input = cur
				goto raw
			} else if c == escapeChar {
				c2, l2 := utf8.DecodeRuneInString(cur)
				cur = cur[l2:]
				if strings.ContainsRune(doubleEscapeChars, c2) {
					buf.WriteString(input[0 : len(input)-len(cur)-l-l2])
					if c2 == '\n' {
					} else {
						buf.WriteRune(c2)
					}
					input = cur
				}
			}
		}
		return "", "", UnterminatedDoubleQuoteError
	}

done:
	return buf.String(), input, nil
}

// go-shellquote ends here.

func run_cmd( s string ) string {

	fmt.Println("exec:", s)

	args, _ := Split( s )

	// cmd := exec.Command( s )

	cmd := exec.Command( args[0], args[1:]... )

	var out bytes.Buffer
	var errorOutput bytes.Buffer

	cmd.Stdout = &out
	cmd.Stderr = &errorOutput

	err2 := cmd.Run()

	outputString := out.String()

	if err2 != nil {
		log.Println( err2 )
		return errorOutput.String()
	}

	outputString = strings.Replace( outputString, "\n", "
", -1 )

	return outputString

}

func handler(w http.ResponseWriter, r *http.Request) {

	fmt.Fprintf( w, "<!doctype html><meta charset=\"utf-8\" /><title>go-web-shell</title><form method=\"post\"><input type=\"text\" name=\"c\" id=\"c\" size=\"50\" />
<input type=\"submit\" value=\"Ok\" /></form>" )

	if r.Method == "POST" {

		fmt.Println( r.FormValue("c") )

		input_cmd := r.FormValue("c")

		fmt.Fprintf( w, run_cmd( input_cmd )  )

	}

}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}
<|endoftext|>


<commit_before>package web

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"image/color"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/StackExchange/bosun/_third_party/github.com/MiniProfiler/go/miniprofiler"
	"github.com/StackExchange/bosun/_third_party/github.com/StackExchange/scollector/metadata"
	"github.com/StackExchange/bosun/_third_party/github.com/StackExchange/scollector/opentsdb"
	svg "github.com/StackExchange/bosun/_third_party/github.com/ajstarks/svgo"
	"github.com/StackExchange/bosun/_third_party/github.com/bradfitz/slice"
	"github.com/StackExchange/bosun/_third_party/github.com/gorilla/mux"
	"github.com/StackExchange/bosun/_third_party/github.com/vdobler/chart"
	"github.com/StackExchange/bosun/_third_party/github.com/vdobler/chart/svgg"
	"github.com/StackExchange/bosun/expr"
	"github.com/StackExchange/bosun/expr/parse"
)

// Graph takes an OpenTSDB request data structure and queries OpenTSDB. Use the
// json parameter to pass JSON. Use the b64 parameter to pass base64-encoded
// JSON.
func Graph(t miniprofiler.Timer, w http.ResponseWriter, r *http.Request) (interface{}, error) {
	j := []byte(r.FormValue("json"))
	if bs := r.FormValue("b64"); bs != "" {
		b, err := base64.URLEncoding.DecodeString(bs)
		if err != nil {
			return nil, err
		}
		j = b
	}
	if len(j) == 0 {
		return nil, fmt.Errorf("either json or b64 required")
	}
	oreq, err := opentsdb.RequestFromJSON(j)
	if err != nil {
		return nil, err
	}
	ads_v := r.FormValue("autods")
	if ads_v != "" {
		ads_i, err := strconv.Atoi(ads_v)
		if err != nil {
			return nil, err
		}
		if err := oreq.AutoDownsample(ads_i); err != nil {
			return nil, err
		}
	}
	ar := make(map[int]bool)
	for _, v := range r.Form["autorate"] {
		if i, err := strconv.Atoi(v); err == nil {
			ar[i] = true
		}
	}
	for i, q := range oreq.Queries {
		if err := schedule.Search.Expand(q); err != nil {
			return nil, err
		}
		if ar[i] {
			ms := schedule.GetMetadata(q.Metric, nil)
			q.Rate = true
			q.RateOptions = opentsdb.RateOptions{
				Counter:    true,
				ResetValue: 1,
			}
			for _, m := range ms {
				if m.Name == "rate" {
					switch m.Value {
					case metadata.Gauge:
						q.Rate = false
						q.RateOptions.Counter = false
					case metadata.Rate:
						q.RateOptions.Counter = false
					}
					break
				}
			}
		}
	}
	var tr opentsdb.ResponseSet
	b, _ := json.MarshalIndent(oreq, "", "  ")
	t.StepCustomTiming("tsdb", "query", string(b), func() {
		tr, err = oreq.Query(schedule.Conf.TsdbHost)
	})
	if err != nil {
		return nil, err
	}
	cs, err := makeChart(tr)
	if err != nil {
		return nil, err
	}
	if _, present := r.Form["png"]; present {
		c := chart.ScatterChart{
			Title: fmt.Sprintf("%v - %v", oreq.Start, oreq.End),
		}
		c.XRange.Time = true
		for ri, r := range cs {
			pts := make([]chart.EPoint, len(r.Data))
			for idx, v := range r.Data {
				pts[idx].X = v[0]
				pts[idx].Y = v[1]
			}
			slice.Sort(pts, func(i, j int) bool {
				return pts[i].X < pts[j].X
			})
			c.AddData(r.Name, pts, chart.PlotStyleLinesPoints, autostyle(ri))
		}
		w.Header().Set("Content-Type", "image/svg+xml")
		white := color.RGBA{0xff, 0xff, 0xff, 0xff}
		const width = 800
		const height = 600
		s := svg.New(w)
		s.Start(width, height)
		s.Rect(0, 0, width, height, "fill: #ffffff")
		sgr := svgg.AddTo(s, 0, 0, width, height, "", 12, white)
		c.Plot(sgr)
		s.End()
		return nil, nil
	}
	return struct {
		Queries []string
		Series  []*chartSeries
	}{
		QFromR(oreq),
		cs,
	}, nil
}

var chartColors = []color.Color{
	color.NRGBA{0xe4, 0x1a, 0x1c, 0xff},
	color.NRGBA{0x37, 0x7e, 0xb8, 0xff},
	color.NRGBA{0x4d, 0xaf, 0x4a, 0xff},
	color.NRGBA{0x98, 0x4e, 0xa3, 0xff},
	color.NRGBA{0xff, 0x7f, 0x00, 0xff},
	color.NRGBA{0xa6, 0x56, 0x28, 0xff},
	color.NRGBA{0xf7, 0x81, 0xbf, 0xff},
	color.NRGBA{0x99, 0x99, 0x99, 0xff},
}

func autostyle(i int) chart.Style {
	c := chartColors[i%len(chartColors)]
	return chart.Style{
		// 0 uses a default
		SymbolSize: 0.00001,
		LineStyle:  chart.SolidLine,
		LineWidth:  1,
		LineColor:  c,
	}
}

func QFromR(req *opentsdb.Request) []string {
	queries := make([]string, len(req.Queries))
	var start, end string
	if s, ok := req.Start.(string); ok && strings.Contains(s, "-ago") {
		start = strings.TrimSuffix(s, "-ago")
	}
	if s, ok := req.End.(string); ok && strings.Contains(s, "-ago") {
		end = strings.TrimSuffix(s, "-ago")
	}
	for i, q := range req.Queries {
		queries[i] = fmt.Sprintf(`q("%v", "%v", "%v")`, q, start, end)
	}
	return queries
}

func ExprGraph(t miniprofiler.Timer, w http.ResponseWriter, r *http.Request) (interface{}, error) {
	vars := mux.Vars(r)
	bs := vars["bs"]
	b, err := base64.URLEncoding.DecodeString(bs)
	if err != nil {
		return nil, err
	}
	q := string(b)
	if len(q) == 0 {
		return nil, fmt.Errorf("missing expression")
	}
	e, err := expr.New(q)
	if err != nil {
		return nil, err
	} else if e.Root.Return() != parse.TYPE_SERIES {
		return nil, fmt.Errorf("egraph: requires an expression that returns a series")
	}
	autods := 1000
	if a := r.FormValue("autods"); a != "" {
		i, err := strconv.Atoi(a)
		if err != nil {
			return nil, err
		}
		autods = i
	}
	now := time.Now().UTC()
	if n := r.FormValue("now"); n != "" {
		i, err := strconv.ParseInt(n, 10, 64)
		if err != nil {
			return nil, err
		}
		now = time.Unix(i, 0).UTC()
	}
	res, _, err := e.Execute(opentsdb.NewCache(schedule.Conf.TsdbHost, schedule.Conf.ResponseLimit), t, now, autods, false, schedule.Search, schedule.Lookups)
	if err != nil {
		return nil, err
	}
	c := chart.ScatterChart{
		Title: fmt.Sprintf("%s - %s", q, now.Format(time.RFC1123)),
	}
	c.XRange.Time = true
	for ri, r := range res.Results {
		rv := r.Value.(expr.Series)
		pts := make([]chart.EPoint, len(rv))
		idx := 0
		for k, v := range rv {
			i, err := strconv.ParseInt(k, 10, 64)
			if err != nil {
				return nil, err
			}
			//names[idx] = time.Unix(i, 0).Format("02 Jan 15:04")
			pts[idx].X = float64(i)
			pts[idx].Y = float64(v)
			idx++
		}
		slice.Sort(pts, func(i, j int) bool {
			return pts[i].X < pts[j].X
		})
		c.AddData(r.Group.String(), pts, chart.PlotStyleLinesPoints, autostyle(ri))
	}
	w.Header().Set("Content-Type", "image/svg+xml")
	white := color.RGBA{0xff, 0xff, 0xff, 0xff}
	const width = 800
	const height = 600
	s := svg.New(w)
	s.Start(width, height)
	s.Rect(0, 0, width, height, "fill: #ffffff")
	sgr := svgg.AddTo(s, 0, 0, width, height, "", 12, white)
	c.Plot(sgr)
	s.End()
	return nil, err
}

func makeChart(r opentsdb.ResponseSet) ([]*chartSeries, error) {
	var series []*chartSeries
	for _, resp := range r {
		dps := make([][2]float64, 0)
		for k, v := range resp.DPS {
			ki, err := strconv.ParseInt(k, 10, 64)
			if err != nil {
				return nil, err
			}
			dps = append(dps, [2]float64{float64(ki), float64(v)})
		}
		if len(dps) > 0 {
			slice.Sort(dps, func(i, j int) bool {
				return dps[i][0] < dps[j][0]
			})
			name := resp.Metric
			if len(resp.Tags) > 0 {
				name += resp.Tags.String()
			}
			series = append(series, &chartSeries{
				Name: name,
				Data: dps,
			})
		}
	}
	return series, nil
}

type chartSeries struct {
	Name string
	Data [][2]float64
}
<commit_msg>Determine queries before search expansion<commit_after>package web

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"image/color"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/StackExchange/bosun/_third_party/github.com/MiniProfiler/go/miniprofiler"
	"github.com/StackExchange/bosun/_third_party/github.com/StackExchange/scollector/metadata"
	"github.com/StackExchange/bosun/_third_party/github.com/StackExchange/scollector/opentsdb"
	svg "github.com/StackExchange/bosun/_third_party/github.com/ajstarks/svgo"
	"github.com/StackExchange/bosun/_third_party/github.com/bradfitz/slice"
	"github.com/StackExchange/bosun/_third_party/github.com/gorilla/mux"
	"github.com/StackExchange/bosun/_third_party/github.com/vdobler/chart"
	"github.com/StackExchange/bosun/_third_party/github.com/vdobler/chart/svgg"
	"github.com/StackExchange/bosun/expr"
	"github.com/StackExchange/bosun/expr/parse"
)

// Graph takes an OpenTSDB request data structure and queries OpenTSDB. Use the
// json parameter to pass JSON. Use the b64 parameter to pass base64-encoded
// JSON.
func Graph(t miniprofiler.Timer, w http.ResponseWriter, r *http.Request) (interface{}, error) {
	j := []byte(r.FormValue("json"))
	if bs := r.FormValue("b64"); bs != "" {
		b, err := base64.URLEncoding.DecodeString(bs)
		if err != nil {
			return nil, err
		}
		j = b
	}
	if len(j) == 0 {
		return nil, fmt.Errorf("either json or b64 required")
	}
	oreq, err := opentsdb.RequestFromJSON(j)
	if err != nil {
		return nil, err
	}
	ads_v := r.FormValue("autods")
	if ads_v != "" {
		ads_i, err := strconv.Atoi(ads_v)
		if err != nil {
			return nil, err
		}
		if err := oreq.AutoDownsample(ads_i); err != nil {
			return nil, err
		}
	}
	ar := make(map[int]bool)
	for _, v := range r.Form["autorate"] {
		if i, err := strconv.Atoi(v); err == nil {
			ar[i] = true
		}
	}
	queries := QFromR(oreq)
	for i, q := range oreq.Queries {
		if err := schedule.Search.Expand(q); err != nil {
			return nil, err
		}
		if ar[i] {
			ms := schedule.GetMetadata(q.Metric, nil)
			q.Rate = true
			q.RateOptions = opentsdb.RateOptions{
				Counter:    true,
				ResetValue: 1,
			}
			for _, m := range ms {
				if m.Name == "rate" {
					switch m.Value {
					case metadata.Gauge:
						q.Rate = false
						q.RateOptions.Counter = false
					case metadata.Rate:
						q.RateOptions.Counter = false
					}
					break
				}
			}
		}
	}
	var tr opentsdb.ResponseSet
	b, _ := json.MarshalIndent(oreq, "", "  ")
	t.StepCustomTiming("tsdb", "query", string(b), func() {
		tr, err = oreq.Query(schedule.Conf.TsdbHost)
	})
	if err != nil {
		return nil, err
	}
	cs, err := makeChart(tr)
	if err != nil {
		return nil, err
	}
	if _, present := r.Form["png"]; present {
		c := chart.ScatterChart{
			Title: fmt.Sprintf("%v - %v", oreq.Start, oreq.End),
		}
		c.XRange.Time = true
		for ri, r := range cs {
			pts := make([]chart.EPoint, len(r.Data))
			for idx, v := range r.Data {
				pts[idx].X = v[0]
				pts[idx].Y = v[1]
			}
			slice.Sort(pts, func(i, j int) bool {
				return pts[i].X < pts[j].X
			})
			c.AddData(r.Name, pts, chart.PlotStyleLinesPoints, autostyle(ri))
		}
		w.Header().Set("Content-Type", "image/svg+xml")
		white := color.RGBA{0xff, 0xff, 0xff, 0xff}
		const width = 800
		const height = 600
		s := svg.New(w)
		s.Start(width, height)
		s.Rect(0, 0, width, height, "fill: #ffffff")
		sgr := svgg.AddTo(s, 0, 0, width, height, "", 12, white)
		c.Plot(sgr)
		s.End()
		return nil, nil
	}
	return struct {
		Queries []string
		Series  []*chartSeries
	}{
		queries,
		cs,
	}, nil
}

var chartColors = []color.Color{
	color.NRGBA{0xe4, 0x1a, 0x1c, 0xff},
	color.NRGBA{0x37, 0x7e, 0xb8, 0xff},
	color.NRGBA{0x4d, 0xaf, 0x4a, 0xff},
	color.NRGBA{0x98, 0x4e, 0xa3, 0xff},
	color.NRGBA{0xff, 0x7f, 0x00, 0xff},
	color.NRGBA{0xa6, 0x56, 0x28, 0xff},
	color.NRGBA{0xf7, 0x81, 0xbf, 0xff},
	color.NRGBA{0x99, 0x99, 0x99, 0xff},
}

func autostyle(i int) chart.Style {
	c := chartColors[i%len(chartColors)]
	return chart.Style{
		// 0 uses a default
		SymbolSize: 0.00001,
		LineStyle:  chart.SolidLine,
		LineWidth:  1,
		LineColor:  c,
	}
}

func QFromR(req *opentsdb.Request) []string {
	queries := make([]string, len(req.Queries))
	var start, end string
	if s, ok := req.Start.(string); ok && strings.Contains(s, "-ago") {
		start = strings.TrimSuffix(s, "-ago")
	}
	if s, ok := req.End.(string); ok && strings.Contains(s, "-ago") {
		end = strings.TrimSuffix(s, "-ago")
	}
	for i, q := range req.Queries {
		queries[i] = fmt.Sprintf(`q("%v", "%v", "%v")`, q, start, end)
	}
	return queries
}

func ExprGraph(t miniprofiler.Timer, w http.ResponseWriter, r *http.Request) (interface{}, error) {
	vars := mux.Vars(r)
	bs := vars["bs"]
	b, err := base64.URLEncoding.DecodeString(bs)
	if err != nil {
		return nil, err
	}
	q := string(b)
	if len(q) == 0 {
		return nil, fmt.Errorf("missing expression")
	}
	e, err := expr.New(q)
	if err != nil {
		return nil, err
	} else if e.Root.Return() != parse.TYPE_SERIES {
		return nil, fmt.Errorf("egraph: requires an expression that returns a series")
	}
	autods := 1000
	if a := r.FormValue("autods"); a != "" {
		i, err := strconv.Atoi(a)
		if err != nil {
			return nil, err
		}
		autods = i
	}
	now := time.Now().UTC()
	if n := r.FormValue("now"); n != "" {
		i, err := strconv.ParseInt(n, 10, 64)
		if err != nil {
			return nil, err
		}
		now = time.Unix(i, 0).UTC()
	}
	res, _, err := e.Execute(opentsdb.NewCache(schedule.Conf.TsdbHost, schedule.Conf.ResponseLimit), t, now, autods, false, schedule.Search, schedule.Lookups)
	if err != nil {
		return nil, err
	}
	c := chart.ScatterChart{
		Title: fmt.Sprintf("%s - %s", q, now.Format(time.RFC1123)),
	}
	c.XRange.Time = true
	for ri, r := range res.Results {
		rv := r.Value.(expr.Series)
		pts := make([]chart.EPoint, len(rv))
		idx := 0
		for k, v := range rv {
			i, err := strconv.ParseInt(k, 10, 64)
			if err != nil {
				return nil, err
			}
			//names[idx] = time.Unix(i, 0).Format("02 Jan 15:04")
			pts[idx].X = float64(i)
			pts[idx].Y = float64(v)
			idx++
		}
		slice.Sort(pts, func(i, j int) bool {
			return pts[i].X < pts[j].X
		})
		c.AddData(r.Group.String(), pts, chart.PlotStyleLinesPoints, autostyle(ri))
	}
	w.Header().Set("Content-Type", "image/svg+xml")
	white := color.RGBA{0xff, 0xff, 0xff, 0xff}
	const width = 800
	const height = 600
	s := svg.New(w)
	s.Start(width, height)
	s.Rect(0, 0, width, height, "fill: #ffffff")
	sgr := svgg.AddTo(s, 0, 0, width, height, "", 12, white)
	c.Plot(sgr)
	s.End()
	return nil, err
}

func makeChart(r opentsdb.ResponseSet) ([]*chartSeries, error) {
	var series []*chartSeries
	for _, resp := range r {
		dps := make([][2]float64, 0)
		for k, v := range resp.DPS {
			ki, err := strconv.ParseInt(k, 10, 64)
			if err != nil {
				return nil, err
			}
			dps = append(dps, [2]float64{float64(ki), float64(v)})
		}
		if len(dps) > 0 {
			slice.Sort(dps, func(i, j int) bool {
				return dps[i][0] < dps[j][0]
			})
			name := resp.Metric
			if len(resp.Tags) > 0 {
				name += resp.Tags.String()
			}
			series = append(series, &chartSeries{
				Name: name,
				Data: dps,
			})
		}
	}
	return series, nil
}

type chartSeries struct {
	Name string
	Data [][2]float64
}
<|endoftext|>


<commit_before>// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/tsuna/gohbase (interfaces: AdminClient)

// Package mock is a generated GoMock package.
package mock

import (
	gomock "github.com/golang/mock/gomock"
	hrpc "github.com/tsuna/gohbase/hrpc"
	pb "github.com/tsuna/gohbase/pb"
	reflect "reflect"
)

// MockAdminClient is a mock of AdminClient interface
type MockAdminClient struct {
	ctrl     *gomock.Controller
	recorder *MockAdminClientMockRecorder
}

// MockAdminClientMockRecorder is the mock recorder for MockAdminClient
type MockAdminClientMockRecorder struct {
	mock *MockAdminClient
}

// NewMockAdminClient creates a new mock instance
func NewMockAdminClient(ctrl *gomock.Controller) *MockAdminClient {
	mock := &MockAdminClient{ctrl: ctrl}
	mock.recorder = &MockAdminClientMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockAdminClient) EXPECT() *MockAdminClientMockRecorder {
	return m.recorder
}

// ClusterStatus mocks base method
func (m *MockAdminClient) ClusterStatus() (*pb.ClusterStatus, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ClusterStatus")
	ret0, _ := ret[0].(*pb.ClusterStatus)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ClusterStatus indicates an expected call of ClusterStatus
func (mr *MockAdminClientMockRecorder) ClusterStatus() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClusterStatus", reflect.TypeOf((*MockAdminClient)(nil).ClusterStatus))
}

// CreateSnapshot mocks base method
func (m *MockAdminClient) CreateSnapshot(arg0 *hrpc.Snapshot) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateSnapshot", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// CreateSnapshot indicates an expected call of CreateSnapshot
func (mr *MockAdminClientMockRecorder) CreateSnapshot(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSnapshot", reflect.TypeOf((*MockAdminClient)(nil).CreateSnapshot), arg0)
}

// CreateTable mocks base method
func (m *MockAdminClient) CreateTable(arg0 *hrpc.CreateTable) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateTable", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// CreateTable indicates an expected call of CreateTable
func (mr *MockAdminClientMockRecorder) CreateTable(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTable", reflect.TypeOf((*MockAdminClient)(nil).CreateTable), arg0)
}

// DeleteSnapshot mocks base method
func (m *MockAdminClient) DeleteSnapshot(arg0 *hrpc.Snapshot) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteSnapshot", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// DeleteSnapshot indicates an expected call of DeleteSnapshot
func (mr *MockAdminClientMockRecorder) DeleteSnapshot(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSnapshot", reflect.TypeOf((*MockAdminClient)(nil).DeleteSnapshot), arg0)
}

// DeleteTable mocks base method
func (m *MockAdminClient) DeleteTable(arg0 *hrpc.DeleteTable) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteTable", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// DeleteTable indicates an expected call of DeleteTable
func (mr *MockAdminClientMockRecorder) DeleteTable(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTable", reflect.TypeOf((*MockAdminClient)(nil).DeleteTable), arg0)
}

// DisableTable mocks base method
func (m *MockAdminClient) DisableTable(arg0 *hrpc.DisableTable) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DisableTable", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// DisableTable indicates an expected call of DisableTable
func (mr *MockAdminClientMockRecorder) DisableTable(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableTable", reflect.TypeOf((*MockAdminClient)(nil).DisableTable), arg0)
}

// EnableTable mocks base method
func (m *MockAdminClient) EnableTable(arg0 *hrpc.EnableTable) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "EnableTable", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// EnableTable indicates an expected call of EnableTable
func (mr *MockAdminClientMockRecorder) EnableTable(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableTable", reflect.TypeOf((*MockAdminClient)(nil).EnableTable), arg0)
}

// ListSnapshots mocks base method
func (m *MockAdminClient) ListSnapshots(arg0 *hrpc.ListSnapshots) ([]*pb.SnapshotDescription, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListSnapshots", arg0)
	ret0, _ := ret[0].([]*pb.SnapshotDescription)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListSnapshots indicates an expected call of ListSnapshots
func (mr *MockAdminClientMockRecorder) ListSnapshots(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSnapshots", reflect.TypeOf((*MockAdminClient)(nil).ListSnapshots), arg0)
}

// ListTableNames mocks base method
func (m *MockAdminClient) ListTableNames(arg0 *hrpc.ListTableNames) ([]*pb.TableName, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListTableNames", arg0)
	ret0, _ := ret[0].([]*pb.TableName)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListTableNames indicates an expected call of ListTableNames
func (mr *MockAdminClientMockRecorder) ListTableNames(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTableNames", reflect.TypeOf((*MockAdminClient)(nil).ListTableNames), arg0)
}

// RestoreSnapshot mocks base method
func (m *MockAdminClient) RestoreSnapshot(arg0 *hrpc.Snapshot) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RestoreSnapshot", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// RestoreSnapshot indicates an expected call of RestoreSnapshot
func (mr *MockAdminClientMockRecorder) RestoreSnapshot(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoreSnapshot", reflect.TypeOf((*MockAdminClient)(nil).RestoreSnapshot), arg0)
}
<commit_msg>test/mock: regenerate MockAdminClient to reflect new methods<commit_after>// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/tsuna/gohbase (interfaces: AdminClient)

// Package mock is a generated GoMock package.
package mock

import (
	gomock "github.com/golang/mock/gomock"
	hrpc "github.com/tsuna/gohbase/hrpc"
	pb "github.com/tsuna/gohbase/pb"
	reflect "reflect"
)

// MockAdminClient is a mock of AdminClient interface
type MockAdminClient struct {
	ctrl     *gomock.Controller
	recorder *MockAdminClientMockRecorder
}

// MockAdminClientMockRecorder is the mock recorder for MockAdminClient
type MockAdminClientMockRecorder struct {
	mock *MockAdminClient
}

// NewMockAdminClient creates a new mock instance
func NewMockAdminClient(ctrl *gomock.Controller) *MockAdminClient {
	mock := &MockAdminClient{ctrl: ctrl}
	mock.recorder = &MockAdminClientMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockAdminClient) EXPECT() *MockAdminClientMockRecorder {
	return m.recorder
}

// ClusterStatus mocks base method
func (m *MockAdminClient) ClusterStatus() (*pb.ClusterStatus, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ClusterStatus")
	ret0, _ := ret[0].(*pb.ClusterStatus)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ClusterStatus indicates an expected call of ClusterStatus
func (mr *MockAdminClientMockRecorder) ClusterStatus() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClusterStatus", reflect.TypeOf((*MockAdminClient)(nil).ClusterStatus))
}

// CreateSnapshot mocks base method
func (m *MockAdminClient) CreateSnapshot(arg0 *hrpc.Snapshot) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateSnapshot", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// CreateSnapshot indicates an expected call of CreateSnapshot
func (mr *MockAdminClientMockRecorder) CreateSnapshot(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSnapshot", reflect.TypeOf((*MockAdminClient)(nil).CreateSnapshot), arg0)
}

// CreateTable mocks base method
func (m *MockAdminClient) CreateTable(arg0 *hrpc.CreateTable) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "CreateTable", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// CreateTable indicates an expected call of CreateTable
func (mr *MockAdminClientMockRecorder) CreateTable(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTable", reflect.TypeOf((*MockAdminClient)(nil).CreateTable), arg0)
}

// DeleteSnapshot mocks base method
func (m *MockAdminClient) DeleteSnapshot(arg0 *hrpc.Snapshot) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteSnapshot", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// DeleteSnapshot indicates an expected call of DeleteSnapshot
func (mr *MockAdminClientMockRecorder) DeleteSnapshot(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSnapshot", reflect.TypeOf((*MockAdminClient)(nil).DeleteSnapshot), arg0)
}

// DeleteTable mocks base method
func (m *MockAdminClient) DeleteTable(arg0 *hrpc.DeleteTable) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteTable", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// DeleteTable indicates an expected call of DeleteTable
func (mr *MockAdminClientMockRecorder) DeleteTable(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTable", reflect.TypeOf((*MockAdminClient)(nil).DeleteTable), arg0)
}

// DisableTable mocks base method
func (m *MockAdminClient) DisableTable(arg0 *hrpc.DisableTable) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DisableTable", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// DisableTable indicates an expected call of DisableTable
func (mr *MockAdminClientMockRecorder) DisableTable(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableTable", reflect.TypeOf((*MockAdminClient)(nil).DisableTable), arg0)
}

// EnableTable mocks base method
func (m *MockAdminClient) EnableTable(arg0 *hrpc.EnableTable) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "EnableTable", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// EnableTable indicates an expected call of EnableTable
func (mr *MockAdminClientMockRecorder) EnableTable(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableTable", reflect.TypeOf((*MockAdminClient)(nil).EnableTable), arg0)
}

// ListSnapshots mocks base method
func (m *MockAdminClient) ListSnapshots(arg0 *hrpc.ListSnapshots) ([]*pb.SnapshotDescription, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListSnapshots", arg0)
	ret0, _ := ret[0].([]*pb.SnapshotDescription)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListSnapshots indicates an expected call of ListSnapshots
func (mr *MockAdminClientMockRecorder) ListSnapshots(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListSnapshots", reflect.TypeOf((*MockAdminClient)(nil).ListSnapshots), arg0)
}

// ListTableNames mocks base method
func (m *MockAdminClient) ListTableNames(arg0 *hrpc.ListTableNames) ([]*pb.TableName, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ListTableNames", arg0)
	ret0, _ := ret[0].([]*pb.TableName)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListTableNames indicates an expected call of ListTableNames
func (mr *MockAdminClientMockRecorder) ListTableNames(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTableNames", reflect.TypeOf((*MockAdminClient)(nil).ListTableNames), arg0)
}

// MoveRegion mocks base method
func (m *MockAdminClient) MoveRegion(arg0 *hrpc.MoveRegion) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "MoveRegion", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// MoveRegion indicates an expected call of MoveRegion
func (mr *MockAdminClientMockRecorder) MoveRegion(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MoveRegion", reflect.TypeOf((*MockAdminClient)(nil).MoveRegion), arg0)
}

// RestoreSnapshot mocks base method
func (m *MockAdminClient) RestoreSnapshot(arg0 *hrpc.Snapshot) error {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RestoreSnapshot", arg0)
	ret0, _ := ret[0].(error)
	return ret0
}

// RestoreSnapshot indicates an expected call of RestoreSnapshot
func (mr *MockAdminClientMockRecorder) RestoreSnapshot(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RestoreSnapshot", reflect.TypeOf((*MockAdminClient)(nil).RestoreSnapshot), arg0)
}

// SetBalancer mocks base method
func (m *MockAdminClient) SetBalancer(arg0 *hrpc.SetBalancer) (bool, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "SetBalancer", arg0)
	ret0, _ := ret[0].(bool)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// SetBalancer indicates an expected call of SetBalancer
func (mr *MockAdminClientMockRecorder) SetBalancer(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBalancer", reflect.TypeOf((*MockAdminClient)(nil).SetBalancer), arg0)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
	"strconv"
)

func RouteHandler() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Write it back to the client.
		log.Println("[RouteHandler]", r.Method, r.URL, r.UserAgent())
		fmt.Fprintf(w, "howdy")
	})
}

func main() {
	port := 8080
	portstring := strconv.Itoa(port)

	http.Handle("/", RouteHandler())

	log.Println("Starting GO webserver on port", portstring)
	err := http.ListenAndServe(":"+portstring, nil)
	if err != nil {
		log.Fatal("ListenAndServe error: ", err)
		os.Exit(1)
	}
}
<commit_msg>Got basic proxy working<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

var target *string

func main() {
	target = flag.String("target", "http://stackoverflow.com", "target URL for reverse proxy")
	flag.Parse()
	http.HandleFunc("/", report)
	log.Fatal(http.ListenAndServe("127.0.0.1:8080", nil))
}

func report(w http.ResponseWriter, r *http.Request) {

	uri := *target + r.RequestURI

	fmt.Println(r.Method + ": " + uri)

	if r.Method == "POST" {
		body, err := ioutil.ReadAll(r.Body)
		fatal(err)
		fmt.Printf("Body: %v\n", string(body))
	}

	rr, err := http.NewRequest(r.Method, uri, r.Body)
	fatal(err)
	copyHeader(r.Header, &rr.Header)

	// Create a client and query the target
	var transport http.Transport
	resp, err := transport.RoundTrip(rr)
	fatal(err)

	fmt.Printf("Resp-Headers: %v\n", resp.Header)

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	fatal(err)

	dH := w.Header()
	copyHeader(resp.Header, &dH)
	dH.Add("Requested-Host", rr.Host)

	w.Write(body)
}

func fatal(err error) {
	if err != nil {
		log.Fatal(err)
		os.Exit(1)
	}
}

func copyHeader(source http.Header, dest *http.Header) {
	for n, v := range source {
		for _, vv := range v {
			dest.Add(n, vv)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"html/template"
	"log"
	"net/http"

	"github.com/julienschmidt/httprouter"
)

//The Post struct is used to record information about each blog post
//Each Post should be named using the post date
type Post struct {
	Title string
	Views int
}

func main() {
	fmt.Println("webserver started")

	router := httprouter.New()

	router.GET("/Glob", testGlob)
	router.GET("/Files", testFiles)
	//password := input args for password
	//router.GET("/", handleIndex)
	//router.GET("/contact", handleContact)
	//router.GET("/projects", handleProjects)
	//router.GET("/posts", handlePostsIndex)
	//router.GET("/posts/*", handlePost)
	//router.GET("/stats", handleStats)
	//router.GET("/refresh/" + password, handleRefresh)

	http.Handle("/", router)

	log.Println("Listening...")
	log.Fatal(http.ListenAndServe(":3000", nil))
}

func testFiles(w http.ResponseWriter, r *http.Request, params httprouter.Params) {

	mock := Post{"Test Post", 20}

	tmpl := template.Must(template.ParseFiles("tmpl/wrapper.html", "tmpl/post.html"))

	//ExecuteTemplate writes the template to w, writing "indexPage" as the main as defined
	//in index.html, and with a data interface
	err := tmpl.ExecuteTemplate(w, "wrapper", mock)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

}

func testGlob(w http.ResponseWriter, r *http.Request, params httprouter.Params) {

	templates := template.Must(template.ParseGlob("tmpl/*"))

	err := templates.ExecuteTemplate(w, "indexPage", nil)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

}
<commit_msg>made func handlePost to dynamicaly serve posts<commit_after>package main

import (
	"fmt"
	"html/template"
	"log"
	"net/http"

	"github.com/julienschmidt/httprouter"
)

//The Post struct is used to record information about each blog post
//Each Post should be named using the post date
type Post struct {
	Title string
	Views int
}

func main() {
	fmt.Println("webserver started")

	router := httprouter.New()

	router.GET("/Glob", testGlob)
	router.GET("/Files", testFiles)
	//password := input args for password
	//router.GET("/", handleIndex)
	//router.GET("/contact", handleContact)
	//router.GET("/projects", handleProjects)
	//router.GET("/posts", handlePostsIndex)
	router.GET("/posts/:post", handlePost)
	//router.GET("/stats", handleStats)
	//router.GET("/refresh/" + password, handleRefresh)

	http.Handle("/", router)

	log.Println("Listening...")
	log.Fatal(http.ListenAndServe(":3000", nil))
}

func handlePost(w http.ResponseWriter, r *http.Request, params httprouter.Params) {

	mock := Post{"Test Post", 20}

	tmpl := template.Must(template.ParseFiles("tmpl/wrapper.html", "tmpl/"+params.ByName("post")+".html"))

	//ExecuteTemplate writes the template to w, writing "indexPage" as the main as defined
	//in index.html, and with a data interface
	err := tmpl.ExecuteTemplate(w, "wrapper", mock)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

}

func testFiles(w http.ResponseWriter, r *http.Request, params httprouter.Params) {

	mock := Post{"Test Post", 20}

	tmpl := template.Must(template.ParseFiles("tmpl/wrapper.html", "tmpl/post.html"))

	//ExecuteTemplate writes the template to w, writing "indexPage" as the main as defined
	//in index.html, and with a data interface
	err := tmpl.ExecuteTemplate(w, "wrapper", mock)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

}

func testGlob(w http.ResponseWriter, r *http.Request, params httprouter.Params) {

	templates := template.Must(template.ParseGlob("tmpl/*"))

	err := templates.ExecuteTemplate(w, "indexPage", nil)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

}
<|endoftext|>


<commit_before>// Package whitelist implements IP whitelisting for various types
// of connections.
package whitelist

import (
	"errors"
	"log"
	"net"
	"sort"
	"strings"
	"sync"
)

// An ACL stores a list of permitted IP addresses, and handles
// concurrency as needed.
type ACL interface {
	// Permitted takes an IP address, and returns true if the
	// IP address is whitelisted (e.g. permitted access).
	Permitted(net.IP) bool

	// Add takes an IP address and adds it to the whitelist so
	// that it is now permitted.
	Add(net.IP)

	// Remove takes an IP address and drops it from the whitelist
	// so that it is no longer permitted.
	Remove(net.IP)
}

// A BasicWhitelist is a basic map-backed whitelister that uses an
// RWMutex for conccurency. IPv4 addresses are treated differently
// than an IPv6 address; namely, the IPv4 localhost will not match
// the IPv6 localhost.
type Basic struct {
	sync.RWMutex
	ipList map[string]bool
}

// Permitted returns true if the IP has been whitelisted.
func (wl *Basic) Permitted(ip net.IP) bool {
	if ip == nil {
		return false
	}

	wl.RLock()
	defer wl.RUnlock()
	return wl.ipList[ip.String()]
}

// Add whitelists an IP.
func (wl *Basic) Add(ip net.IP) {
	if ip == nil {
		return
	}

	wl.Lock()
	defer wl.Unlock()
	wl.ipList[ip.String()] = true
}

// Remove clears the IP from the whitelist.
func (wl *Basic) Remove(ip net.IP) {
	if ip == nil {
		return
	}

	wl.Lock()
	defer wl.Unlock()
	delete(wl.ipList, ip.String())
}

// NewBasic returns a new initialised basic whitelist.
func NewBasic() *Basic {
	return &Basic{
		ipList: map[string]bool{},
	}
}

// DumpBasic returns a whitelist as a byte slice where each IP is on
// its own line.
func DumpBasic(wl *Basic) []byte {
	wl.RLock()
	defer wl.RUnlock()

	var addrs []string
	for ip := range wl.ipList {
		addrs = append(addrs, ip)
	}

	sort.Strings(addrs)

	addrList := strings.Join(addrs, "\n")
	return []byte(addrList)
}

// LoadBasic loads a whitelist from a byteslice.
func LoadBasic(in []byte) (*Basic, error) {
	wl := NewBasic()
	addrs := strings.Split(string(in), "\n")

	for _, addr := range addrs {
		ip := net.ParseIP(addr)
		if ip == nil {
			return nil, errors.New("whitelist: invalid address")
		}
		wl.Add(ip)
	}
	return wl, nil
}

// StubWhitelist allows whitelisting to be added into a system's flow
// without doing anything yet. All operations result in warning log
// messages being printed to stderr. There is no mechanism for
// squelching these messages short of modifying the log package's
// default logger.
type Stub struct{}

// Permitted always returns true, but prints a warning message alerting
// that whitelisting is stubbed.
func (wl *Stub) Permitted(ip net.IP) bool {
	log.Printf("WARNING: whitelist check for %s but whitelisting is stubbed", ip)
	return true
}

// Add prints a warning message about whitelisting being stubbed.
func (wl *Stub) Add(ip net.IP) {
	log.Printf("WARNING: IP %s added to whitelist but whitelisting is stubbed", ip)
}

// Remove prints a warning message about whitelisting being stubbed.
func (wl *Stub) Remove(ip net.IP) {
	log.Printf("WARNING: IP %s removed from whitelist but whitelisting is stubbed", ip)
}

// NewStub returns a new stubbed whitelister.
func NewStub() *Stub {
	log.Println("WARNING: whitelisting is being stubbed")
	return &Stub{}
}
<commit_msg>golint fixes<commit_after>// Package whitelist implements IP whitelisting for various types
// of connections.
package whitelist

import (
	"errors"
	"log"
	"net"
	"sort"
	"strings"
	"sync"
)

// An ACL stores a list of permitted IP addresses, and handles
// concurrency as needed.
type ACL interface {
	// Permitted takes an IP address, and returns true if the
	// IP address is whitelisted (e.g. permitted access).
	Permitted(net.IP) bool

	// Add takes an IP address and adds it to the whitelist so
	// that it is now permitted.
	Add(net.IP)

	// Remove takes an IP address and drops it from the whitelist
	// so that it is no longer permitted.
	Remove(net.IP)
}

// Basic implements a basic map-backed whitelister that uses an
// RWMutex for conccurency. IPv4 addresses are treated differently
// than an IPv6 address; namely, the IPv4 localhost will not match
// the IPv6 localhost.
type Basic struct {
	sync.RWMutex
	ipList map[string]bool
}

// Permitted returns true if the IP has been whitelisted.
func (wl *Basic) Permitted(ip net.IP) bool {
	if ip == nil {
		return false
	}

	wl.RLock()
	defer wl.RUnlock()
	return wl.ipList[ip.String()]
}

// Add whitelists an IP.
func (wl *Basic) Add(ip net.IP) {
	if ip == nil {
		return
	}

	wl.Lock()
	defer wl.Unlock()
	wl.ipList[ip.String()] = true
}

// Remove clears the IP from the whitelist.
func (wl *Basic) Remove(ip net.IP) {
	if ip == nil {
		return
	}

	wl.Lock()
	defer wl.Unlock()
	delete(wl.ipList, ip.String())
}

// NewBasic returns a new initialised basic whitelist.
func NewBasic() *Basic {
	return &Basic{
		ipList: map[string]bool{},
	}
}

// DumpBasic returns a whitelist as a byte slice where each IP is on
// its own line.
func DumpBasic(wl *Basic) []byte {
	wl.RLock()
	defer wl.RUnlock()

	var addrs []string
	for ip := range wl.ipList {
		addrs = append(addrs, ip)
	}

	sort.Strings(addrs)

	addrList := strings.Join(addrs, "\n")
	return []byte(addrList)
}

// LoadBasic loads a whitelist from a byteslice.
func LoadBasic(in []byte) (*Basic, error) {
	wl := NewBasic()
	addrs := strings.Split(string(in), "\n")

	for _, addr := range addrs {
		ip := net.ParseIP(addr)
		if ip == nil {
			return nil, errors.New("whitelist: invalid address")
		}
		wl.Add(ip)
	}
	return wl, nil
}

// Stub allows whitelisting to be added into a system's flow
// without doing anything yet. All operations result in warning log
// messages being printed to stderr. There is no mechanism for
// squelching these messages short of modifying the log package's
// default logger.
type Stub struct{}

// Permitted always returns true, but prints a warning message alerting
// that whitelisting is stubbed.
func (wl *Stub) Permitted(ip net.IP) bool {
	log.Printf("WARNING: whitelist check for %s but whitelisting is stubbed", ip)
	return true
}

// Add prints a warning message about whitelisting being stubbed.
func (wl *Stub) Add(ip net.IP) {
	log.Printf("WARNING: IP %s added to whitelist but whitelisting is stubbed", ip)
}

// Remove prints a warning message about whitelisting being stubbed.
func (wl *Stub) Remove(ip net.IP) {
	log.Printf("WARNING: IP %s removed from whitelist but whitelisting is stubbed", ip)
}

// NewStub returns a new stubbed whitelister.
func NewStub() *Stub {
	log.Println("WARNING: whitelisting is being stubbed")
	return &Stub{}
}
<|endoftext|>


<commit_before>package disruptor

func (this Barrier) Load() int64 {
	minimum := MaxSequenceValue

	for _, item := range this {
		cursor := item[0]
		if cursor < minimum {
			minimum = cursor
		}
	}

	return minimum
}

func NewBarrier(upstream ...*Sequence) Barrier {
	this := Barrier{}
	for i := 0; i < len(upstream); i++ {
		this = append(this, upstream[i])
	}
	return this
}

type Barrier []*Sequence
<commit_msg>Simplified barrier construction.<commit_after>package disruptor

func (this Barrier) Load() int64 {
	minimum := MaxSequenceValue

	for _, item := range this {
		cursor := item[0]
		if cursor < minimum {
			minimum = cursor
		}
	}

	return minimum
}

func NewBarrier(upstream ...*Sequence) Barrier {
	buffer := make([]*Sequence, len(upstream))
	copy(buffer, upstream)
	return Barrier(buffer)
}

type Barrier []*Sequence
<|endoftext|>


<commit_before>package recovery

import (
    "os"
    "io"
    "fmt"
    "net"
    "sync"
    "strconv"
    "encoding/csv"
    "github/paxoscluster/proposal"
)

type Manager struct {
    exclude sync.Mutex
}

func ConstructManager() (*Manager, error) {
    _, err := os.Stat("coldstorage")
    if err != nil { return nil, err }
    return new(Manager), nil
}

// Finishes all writes and permanently locks in preparation for shutdown
func (this *Manager) Finalize() {
    fmt.Println("[ DISK ] Clearing writes before shutdown")
    this.exclude.Lock()
}

// Reads the list of peers from a file on disk
func (this *Manager) RetrieveAddresses() (map[uint64]string, error) {
    this.exclude.Lock()
    defer this.exclude.Unlock()

    addresses := make(map[uint64]string)

    // Checks for existence of peers file
    _, err := os.Stat("coldstorage/peers.csv")
    if err != nil { return nil, err }

    // Opens & reads peers file
    peersFile, err := os.Open("coldstorage/peers.csv")
    if err != nil { return nil, err }
    peersFileReader := csv.NewReader(peersFile)
    records, err := peersFileReader.ReadAll()
    peersFile.Close()
    if err != nil { return nil, err }

    // Reads from & parses peers.csv file
    for _, record := range records {
        if len(record) != 3 { return addresses, fmt.Errorf("Invalid record length in peers file") }
        roleId, err := strconv.ParseUint(record[0], 10, 64)
        if err != nil { return nil, err }
        ipAddress := record[1]
        port := record[2]
        addresses[roleId] = net.JoinHostPort(ipAddress, port)
    }

    return addresses, nil
}

func (this *Manager) RecoverMinProposalId(roleId uint64) (proposal.Id, error) {
    this.exclude.Lock()
    defer this.exclude.Unlock()

    // Checks for existence of directory
    _, err := os.Stat(fmt.Sprintf("coldstorage/%d", roleId))
    if os.IsNotExist(err) {
        return proposal.Default(), nil
    } else if err != nil { return proposal.Default(), err }

    // Checks for existence of file
    proposalFileName := fmt.Sprintf("coldstorage/%d/minproposalid.csv", roleId)
    _, err = os.Stat(proposalFileName)
    if os.IsNotExist(err) {
        return proposal.Default(), nil
    } else if err != nil { return proposal.Default(), err }

    // File exists, therefore read from it
    proposalFile, err := os.Open(proposalFileName)
    if err != nil { return proposal.Default(), err }
    proposalFileReader := csv.NewReader(proposalFile)
    record, err := proposalFileReader.Read()
    proposalFile.Close()
    if err != nil && err != io.EOF { return proposal.Default(), err }
    proposalRole, err := strconv.ParseUint(record[0], 10, 64)
    if err != nil { return proposal.Default(), err }
    sequence, err := strconv.ParseInt(record[1], 10, 64)
    if err != nil { return proposal.Default(), err }

    return proposal.Id{proposalRole, sequence}, nil
}

func (this *Manager) UpdateMinProposalId(roleId uint64, id proposal.Id) error {
    this.exclude.Lock()
    defer this.exclude.Unlock()

    // Ensures existence of directory, creating it if necessary
    _, err := os.Stat(fmt.Sprintf("coldstorage/%d", roleId))
    if os.IsNotExist(err) {
        err = os.Mkdir(fmt.Sprintf("coldstorage/%d", roleId), os.ModeDir)
        if err != nil { return err }
    } else if err != nil { return err }

    // Creates file (automatic overwrite)
    proposalFileName := fmt.Sprintf("coldstorage/%d/minproposalid.csv", roleId)
    proposalFile, err := os.Create(proposalFileName)
    if err != nil { return err }
    defer proposalFile.Close()

    // Writes data to file
    record := []string{strconv.FormatUint(id.RoleId, 10), strconv.FormatInt(id.Sequence, 10)}
    proposalFileWriter := csv.NewWriter(proposalFile)
    err = proposalFileWriter.Write(record)
    if err != nil { return err }
    proposalFileWriter.Flush()
    return nil
}

func (this *Manager) RecoverLog(roleId uint64) ([]string, []proposal.Id, error) {
    this.exclude.Lock()
    defer this.exclude.Unlock()

    // Checks for existence of log file directory
    _, err := os.Stat(fmt.Sprintf("coldstorage/%d", roleId))
    if os.IsNotExist(err) {
        return nil, nil, nil
    } else if err != nil { return nil, nil, err }

    // Checks for existence of log file
    logFileName := fmt.Sprintf("coldstorage/%d/log.csv", roleId)
    _, err = os.Stat(logFileName)
    if os.IsNotExist(err) {
        return nil, nil, nil
    } else if err != nil { return nil, nil, err }

    // Log file exists, therefore read from it
    logFile, err := os.Open(logFileName)
    if err != nil { return nil, nil, err }
    logFileReader := csv.NewReader(logFile)
    records, err := logFileReader.ReadAll()
    logFile.Close()
    if err != nil { return nil, nil, err }

    // Parse records
    var values []string = nil
    var proposals []proposal.Id = nil
    for _, record := range records {
        if len(record) != 3 { return nil, nil, fmt.Errorf("Invalid record length in log file %d", roleId) }
        values = append(values, record[0])
        proposalRole, err := strconv.ParseUint(record[1], 10, 64)
        if err != nil { return nil, nil, err }
        sequence, err := strconv.ParseInt(record[2], 10, 64)
        if err != nil { return nil, nil, err }
        proposals = append(proposals, proposal.Id{proposalRole, sequence})
    }

    return values, proposals, nil
}

// Updates a record in the log file
func (this *Manager) UpdateLogRecord(roleId uint64, index int, value string, id proposal.Id) error {
    this.exclude.Lock()
    defer this.exclude.Unlock()

    // Ensures existence of directory, creating it if necessary
    _, err := os.Stat(fmt.Sprintf("coldstorage/%d", roleId))
    if os.IsNotExist(err) {
        err = os.Mkdir(fmt.Sprintf("coldstorage/%d", roleId), os.ModeDir)
        if err != nil { return err }
    } else if err != nil { return err }

    // If log file exists, read from it
    logFileName := fmt.Sprintf("coldstorage/%d/log.csv", roleId)
    var records [][]string = nil
    _, err = os.Stat(logFileName)
    if err == nil {
        logFile, err := os.Open(logFileName)
        if err != nil { return err }
        logFileReader := csv.NewReader(logFile)
        records, err = logFileReader.ReadAll()
        logFile.Close()
        if err != nil { return err }
    } else if err != nil && !os.IsNotExist(err) { return err }

    // Modifies record
    blank := []string{"", "0", "0"}
    record := []string{value, strconv.FormatUint(id.RoleId, 10), strconv.FormatInt(id.Sequence, 10)}
    for recordCount := len(records); recordCount <= index; recordCount++ {
        records = append(records, blank)
    }
    records[index] = record

    // Writes out log contents
    modifiedLogFile, err := os.Create(logFileName)
    if err != nil { return err }
    defer modifiedLogFile.Close()
    logFileWriter := csv.NewWriter(modifiedLogFile)
    return logFileWriter.WriteAll(records)
}
<commit_msg>Now catches SIGTERM to ensure writes are complete<commit_after>package recovery

import (
    "os"
    "io"
    "fmt"
    "net"
    "sync"
    "strconv"
    "os/signal"
    "encoding/csv"
    "github/paxoscluster/proposal"
)

type Manager struct {
    sigint chan os.Signal
    exclude sync.Mutex
}

// Creates disk access manager for backup & recovery files
func ConstructManager() (*Manager, error) {
    _, err := os.Stat("coldstorage")
    if err != nil { return nil, err }

    newManager := Manager {
        sigint: make(chan os.Signal, 1),
    }
    signal.Notify(newManager.sigint, os.Interrupt)
    go newManager.finalize()

    return &newManager, nil
}

// Finishes all writes and permanently locks in preparation for shutdown
func (this *Manager) finalize() {
    <- this.sigint
    fmt.Println("[ DISK ] Clearing writes before shutdown")
    this.exclude.Lock()
    os.Exit(0)
}

// Reads the list of peers from a file on disk
func (this *Manager) RetrieveAddresses() (map[uint64]string, error) {
    this.exclude.Lock()
    defer this.exclude.Unlock()

    addresses := make(map[uint64]string)

    // Checks for existence of peers file
    _, err := os.Stat("coldstorage/peers.csv")
    if err != nil { return nil, err }

    // Opens & reads peers file
    peersFile, err := os.Open("coldstorage/peers.csv")
    if err != nil { return nil, err }
    peersFileReader := csv.NewReader(peersFile)
    records, err := peersFileReader.ReadAll()
    peersFile.Close()
    if err != nil { return nil, err }

    // Reads from & parses peers.csv file
    for _, record := range records {
        if len(record) != 3 { return addresses, fmt.Errorf("Invalid record length in peers file") }
        roleId, err := strconv.ParseUint(record[0], 10, 64)
        if err != nil { return nil, err }
        ipAddress := record[1]
        port := record[2]
        addresses[roleId] = net.JoinHostPort(ipAddress, port)
    }

    return addresses, nil
}

func (this *Manager) RecoverMinProposalId(roleId uint64) (proposal.Id, error) {
    this.exclude.Lock()
    defer this.exclude.Unlock()

    // Checks for existence of directory
    _, err := os.Stat(fmt.Sprintf("coldstorage/%d", roleId))
    if os.IsNotExist(err) {
        return proposal.Default(), nil
    } else if err != nil { return proposal.Default(), err }

    // Checks for existence of file
    proposalFileName := fmt.Sprintf("coldstorage/%d/minproposalid.csv", roleId)
    _, err = os.Stat(proposalFileName)
    if os.IsNotExist(err) {
        return proposal.Default(), nil
    } else if err != nil { return proposal.Default(), err }

    // File exists, therefore read from it
    proposalFile, err := os.Open(proposalFileName)
    if err != nil { return proposal.Default(), err }
    proposalFileReader := csv.NewReader(proposalFile)
    record, err := proposalFileReader.Read()
    proposalFile.Close()
    if err != nil && err != io.EOF { return proposal.Default(), err }
    proposalRole, err := strconv.ParseUint(record[0], 10, 64)
    if err != nil { return proposal.Default(), err }
    sequence, err := strconv.ParseInt(record[1], 10, 64)
    if err != nil { return proposal.Default(), err }

    return proposal.Id{proposalRole, sequence}, nil
}

func (this *Manager) UpdateMinProposalId(roleId uint64, id proposal.Id) error {
    this.exclude.Lock()
    defer this.exclude.Unlock()

    // Ensures existence of directory, creating it if necessary
    _, err := os.Stat(fmt.Sprintf("coldstorage/%d", roleId))
    if os.IsNotExist(err) {
        err = os.Mkdir(fmt.Sprintf("coldstorage/%d", roleId), os.ModeDir)
        if err != nil { return err }
    } else if err != nil { return err }

    // Creates file (automatic overwrite)
    proposalFileName := fmt.Sprintf("coldstorage/%d/minproposalid.csv", roleId)
    proposalFile, err := os.Create(proposalFileName)
    if err != nil { return err }
    defer proposalFile.Close()

    // Writes data to file
    record := []string{strconv.FormatUint(id.RoleId, 10), strconv.FormatInt(id.Sequence, 10)}
    proposalFileWriter := csv.NewWriter(proposalFile)
    err = proposalFileWriter.Write(record)
    if err != nil { return err }
    proposalFileWriter.Flush()
    return nil
}

func (this *Manager) RecoverLog(roleId uint64) ([]string, []proposal.Id, error) {
    this.exclude.Lock()
    defer this.exclude.Unlock()

    // Checks for existence of log file directory
    _, err := os.Stat(fmt.Sprintf("coldstorage/%d", roleId))
    if os.IsNotExist(err) {
        return nil, nil, nil
    } else if err != nil { return nil, nil, err }

    // Checks for existence of log file
    logFileName := fmt.Sprintf("coldstorage/%d/log.csv", roleId)
    _, err = os.Stat(logFileName)
    if os.IsNotExist(err) {
        return nil, nil, nil
    } else if err != nil { return nil, nil, err }

    // Log file exists, therefore read from it
    logFile, err := os.Open(logFileName)
    if err != nil { return nil, nil, err }
    logFileReader := csv.NewReader(logFile)
    records, err := logFileReader.ReadAll()
    logFile.Close()
    if err != nil { return nil, nil, err }

    // Parse records
    var values []string = nil
    var proposals []proposal.Id = nil
    for _, record := range records {
        if len(record) != 3 { return nil, nil, fmt.Errorf("Invalid record length in log file %d", roleId) }
        values = append(values, record[0])
        proposalRole, err := strconv.ParseUint(record[1], 10, 64)
        if err != nil { return nil, nil, err }
        sequence, err := strconv.ParseInt(record[2], 10, 64)
        if err != nil { return nil, nil, err }
        proposals = append(proposals, proposal.Id{proposalRole, sequence})
    }

    return values, proposals, nil
}

// Updates a record in the log file
func (this *Manager) UpdateLogRecord(roleId uint64, index int, value string, id proposal.Id) error {
    this.exclude.Lock()
    defer this.exclude.Unlock()

    // Ensures existence of directory, creating it if necessary
    _, err := os.Stat(fmt.Sprintf("coldstorage/%d", roleId))
    if os.IsNotExist(err) {
        err = os.Mkdir(fmt.Sprintf("coldstorage/%d", roleId), os.ModeDir)
        if err != nil { return err }
    } else if err != nil { return err }

    // If log file exists, read from it
    logFileName := fmt.Sprintf("coldstorage/%d/log.csv", roleId)
    var records [][]string = nil
    _, err = os.Stat(logFileName)
    if err == nil {
        logFile, err := os.Open(logFileName)
        if err != nil { return err }
        logFileReader := csv.NewReader(logFile)
        records, err = logFileReader.ReadAll()
        logFile.Close()
        if err != nil { return err }
    } else if err != nil && !os.IsNotExist(err) { return err }

    // Modifies record
    blank := []string{"", "0", "0"}
    record := []string{value, strconv.FormatUint(id.RoleId, 10), strconv.FormatInt(id.Sequence, 10)}
    for recordCount := len(records); recordCount <= index; recordCount++ {
        records = append(records, blank)
    }
    records[index] = record

    // Writes out log contents
    modifiedLogFile, err := os.Create(logFileName)
    if err != nil { return err }
    defer modifiedLogFile.Close()
    logFileWriter := csv.NewWriter(modifiedLogFile)
    return logFileWriter.WriteAll(records)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"os"
	"os/user"
	"path"
	"reflect"
	"strconv"
	"strings"
)

var (
	homeDir    string
	selfURL127 string // 127.0.0.1:listenAddr
	selfURLLH  string // localhost:listenAddr

	printVer bool
)

const (
	dotDir             = ".cow"
	blockedFname       = "auto-blocked"
	directFname        = "auto-direct"
	alwaysBlockedFname = "blocked"
	alwaysDirectFname  = "direct"
	chouFname          = "chou"
	rcFname            = "rc"

	version = "0.2.2"
)

var config struct {
	listenAddr    string
	socksAddr     string
	numProc       int
	sshServer     string
	updateBlocked bool
	updateDirect  bool
	logFile       string

	// These are for internal use
	dir               string // directory containing config file and blocked site list
	blockedFile       string // contains blocked domains
	directFile        string // contains sites that can be directly accessed
	alwaysDirectFile  string
	alwaysBlockedFile string
	chouFile          string // chou feng, sites which will be temporary blocked
	rcFile            string
}

func printVersion() {
	fmt.Println("cow-proxy version", version)
}

func init() {
	u, err := user.Current()
	if err != nil {
		errl.Printf("Can't get user information %v", err)
		os.Exit(1)
	}
	homeDir = u.HomeDir

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&config.listenAddr, "listen", "127.0.0.1:7777", "proxy server listen address")
	flag.StringVar(&config.socksAddr, "socks", "127.0.0.1:1080", "socks server address")
	flag.IntVar(&config.numProc, "core", 2, "number of cores to use")
	flag.StringVar(&config.sshServer, "sshServer", "", "remote server which will ssh to and provide sock server")
	flag.BoolVar(&config.updateBlocked, "updateBlocked", true, "update blocked site list")
	flag.BoolVar(&config.updateDirect, "updateDirect", true, "update direct site list")
	flag.StringVar(&config.logFile, "logFile", "", "write output to file, empty means stdout")

	config.dir = path.Join(homeDir, dotDir)
	config.blockedFile = path.Join(config.dir, blockedFname)
	config.directFile = path.Join(config.dir, directFname)
	config.alwaysBlockedFile = path.Join(config.dir, alwaysBlockedFname)
	config.alwaysDirectFile = path.Join(config.dir, alwaysDirectFname)
	config.chouFile = path.Join(config.dir, chouFname)
	config.rcFile = path.Join(config.dir, rcFname)
}

// Tries to open a file, if file not exist, return both nil for os.File and
// err
func openFile(path string) (f *os.File, err error) {
	if f, err = os.Open(path); err != nil {
		if os.IsNotExist(err) {
			return nil, nil
		}
		errl.Println("Error opening file:", path, err)
		return nil, err
	}
	return
}

func parseBool(v string, msg string) bool {
	switch v {
	case "true":
		return true
	case "false":
		return false
	default:
		fmt.Printf("%s should be true or false\n", msg)
		os.Exit(1)
	}
	return false
}

type configParser struct{}

func (p configParser) ParseListen(val string) {
	config.listenAddr = val
}

func (p configParser) ParseSocks(val string) {
	_, port := splitHostPort(val)
	if port == "" {
		fmt.Println("socks server must have port specified")
		os.Exit(1)
	}
	config.socksAddr = val
}

func (p configParser) ParseCore(val string) {
	var err error
	config.numProc, err = strconv.Atoi(val)
	if err != nil {
		fmt.Printf("Config error: core number %s %v", val, err)
		os.Exit(1)
	}
}

func (p configParser) ParseSshServer(val string) {
	config.sshServer = val
}

func (p configParser) ParseUpdateBlocked(val string) {
	config.updateBlocked = parseBool(val, "updateBlocked")
}

func (p configParser) ParseUpdateDirect(val string) {
	config.updateDirect = parseBool(val, "updateDirect")
}

func (p configParser) ParseLogFile(val string) {
	config.logFile = val
}

func parseConfig() {
	f, err := openFile(config.rcFile)
	if f == nil || err != nil {
		return
	}
	defer f.Close()

	fr := bufio.NewReader(f)

	parser := reflect.ValueOf(configParser{})
	zeroMethod := reflect.Value{}

	var line string
	var n int
	for {
		n++
		line, err = ReadLine(fr)
		if err == io.EOF {
			return
		} else if err != nil {
			errl.Printf("Error reading rc file: %v\n", err)
			os.Exit(1)
		}

		if line == "" {
			continue
		}

		line = strings.TrimSpace(line)
		// Ignore comment
		if line[0] == '#' {
			continue
		}

		v := strings.Split(line, "=")
		if len(v) != 2 {
			fmt.Println("Config error: syntax error on line", n)
			os.Exit(1)
		}
		key, val := strings.TrimSpace(v[0]), strings.TrimSpace(v[1])

		methodName := "Parse" + strings.ToUpper(key[0:1]) + key[1:]
		method := parser.MethodByName(methodName)
		if method == zeroMethod {
			fmt.Printf("Config error: no such option \"%s\"\n", key)
			os.Exit(1)
		}
		args := []reflect.Value{reflect.ValueOf(val)}
		method.Call(args)
	}
}

func loadConfig() {
	parseConfig()

	blockedDs.loadDomainList(config.blockedFile)
	directDs.loadDomainList(config.directFile)

	alwaysBlockedDs.loadDomainList(config.alwaysBlockedFile)
	alwaysDirectDs.loadDomainList(config.alwaysDirectFile)
	chouDs.loadDomainList(config.chouFile)

	_, port := splitHostPort(config.listenAddr)
	selfURL127 = "127.0.0.1:" + port
	selfURLLH = "localhost:" + port
}
<commit_msg>Bump version to 0.2.3<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"os"
	"os/user"
	"path"
	"reflect"
	"strconv"
	"strings"
)

var (
	homeDir    string
	selfURL127 string // 127.0.0.1:listenAddr
	selfURLLH  string // localhost:listenAddr

	printVer bool
)

const (
	dotDir             = ".cow"
	blockedFname       = "auto-blocked"
	directFname        = "auto-direct"
	alwaysBlockedFname = "blocked"
	alwaysDirectFname  = "direct"
	chouFname          = "chou"
	rcFname            = "rc"

	version = "0.2.3"
)

var config struct {
	listenAddr    string
	socksAddr     string
	numProc       int
	sshServer     string
	updateBlocked bool
	updateDirect  bool
	logFile       string

	// These are for internal use
	dir               string // directory containing config file and blocked site list
	blockedFile       string // contains blocked domains
	directFile        string // contains sites that can be directly accessed
	alwaysDirectFile  string
	alwaysBlockedFile string
	chouFile          string // chou feng, sites which will be temporary blocked
	rcFile            string
}

func printVersion() {
	fmt.Println("cow-proxy version", version)
}

func init() {
	u, err := user.Current()
	if err != nil {
		errl.Printf("Can't get user information %v", err)
		os.Exit(1)
	}
	homeDir = u.HomeDir

	flag.BoolVar(&printVer, "version", false, "print version")
	flag.StringVar(&config.listenAddr, "listen", "127.0.0.1:7777", "proxy server listen address")
	flag.StringVar(&config.socksAddr, "socks", "127.0.0.1:1080", "socks server address")
	flag.IntVar(&config.numProc, "core", 2, "number of cores to use")
	flag.StringVar(&config.sshServer, "sshServer", "", "remote server which will ssh to and provide sock server")
	flag.BoolVar(&config.updateBlocked, "updateBlocked", true, "update blocked site list")
	flag.BoolVar(&config.updateDirect, "updateDirect", true, "update direct site list")
	flag.StringVar(&config.logFile, "logFile", "", "write output to file, empty means stdout")

	config.dir = path.Join(homeDir, dotDir)
	config.blockedFile = path.Join(config.dir, blockedFname)
	config.directFile = path.Join(config.dir, directFname)
	config.alwaysBlockedFile = path.Join(config.dir, alwaysBlockedFname)
	config.alwaysDirectFile = path.Join(config.dir, alwaysDirectFname)
	config.chouFile = path.Join(config.dir, chouFname)
	config.rcFile = path.Join(config.dir, rcFname)
}

// Tries to open a file, if file not exist, return both nil for os.File and
// err
func openFile(path string) (f *os.File, err error) {
	if f, err = os.Open(path); err != nil {
		if os.IsNotExist(err) {
			return nil, nil
		}
		errl.Println("Error opening file:", path, err)
		return nil, err
	}
	return
}

func parseBool(v string, msg string) bool {
	switch v {
	case "true":
		return true
	case "false":
		return false
	default:
		fmt.Printf("%s should be true or false\n", msg)
		os.Exit(1)
	}
	return false
}

type configParser struct{}

func (p configParser) ParseListen(val string) {
	config.listenAddr = val
}

func (p configParser) ParseSocks(val string) {
	_, port := splitHostPort(val)
	if port == "" {
		fmt.Println("socks server must have port specified")
		os.Exit(1)
	}
	config.socksAddr = val
}

func (p configParser) ParseCore(val string) {
	var err error
	config.numProc, err = strconv.Atoi(val)
	if err != nil {
		fmt.Printf("Config error: core number %s %v", val, err)
		os.Exit(1)
	}
}

func (p configParser) ParseSshServer(val string) {
	config.sshServer = val
}

func (p configParser) ParseUpdateBlocked(val string) {
	config.updateBlocked = parseBool(val, "updateBlocked")
}

func (p configParser) ParseUpdateDirect(val string) {
	config.updateDirect = parseBool(val, "updateDirect")
}

func (p configParser) ParseLogFile(val string) {
	config.logFile = val
}

func parseConfig() {
	f, err := openFile(config.rcFile)
	if f == nil || err != nil {
		return
	}
	defer f.Close()

	fr := bufio.NewReader(f)

	parser := reflect.ValueOf(configParser{})
	zeroMethod := reflect.Value{}

	var line string
	var n int
	for {
		n++
		line, err = ReadLine(fr)
		if err == io.EOF {
			return
		} else if err != nil {
			errl.Printf("Error reading rc file: %v\n", err)
			os.Exit(1)
		}

		if line == "" {
			continue
		}

		line = strings.TrimSpace(line)
		// Ignore comment
		if line[0] == '#' {
			continue
		}

		v := strings.Split(line, "=")
		if len(v) != 2 {
			fmt.Println("Config error: syntax error on line", n)
			os.Exit(1)
		}
		key, val := strings.TrimSpace(v[0]), strings.TrimSpace(v[1])

		methodName := "Parse" + strings.ToUpper(key[0:1]) + key[1:]
		method := parser.MethodByName(methodName)
		if method == zeroMethod {
			fmt.Printf("Config error: no such option \"%s\"\n", key)
			os.Exit(1)
		}
		args := []reflect.Value{reflect.ValueOf(val)}
		method.Call(args)
	}
}

func loadConfig() {
	parseConfig()

	blockedDs.loadDomainList(config.blockedFile)
	directDs.loadDomainList(config.directFile)

	alwaysBlockedDs.loadDomainList(config.alwaysBlockedFile)
	alwaysDirectDs.loadDomainList(config.alwaysDirectFile)
	chouDs.loadDomainList(config.chouFile)

	_, port := splitHostPort(config.listenAddr)
	selfURL127 = "127.0.0.1:" + port
	selfURLLH = "localhost:" + port
}
<|endoftext|>


<commit_before>package kaiju

type Config struct {
	BindHost string `yaml:"bindHost" json:"bindHost"`
	Port     int    `yaml:"bindPort" json:"bindPort"`
}
<commit_msg>support envconfig<commit_after>package kaiju

type Config struct {
	BindHost string `yaml:"bindHost" json:"bindHost" envconfig:"bind_host" default:"localhost"`
	Port     int    `yaml:"bindPort" json:"bindPort" enconfig:"bind_port" default:"8080"`
}
<|endoftext|>


<commit_before>package cluster

import (
	"regexp"
	"time"

	"github.com/Shopify/sarama"
)

var minVersion = sarama.V0_9_0_0

type ConsumerMode uint8

const (
	ConsumerModeMultiplex ConsumerMode = iota
	ConsumerModePartitions
)

// Config extends sarama.Config with Group specific namespace
type Config struct {
	sarama.Config

	// Group is the namespace for group management properties
	Group struct {

		// The strategy to use for the allocation of partitions to consumers (defaults to StrategyRange)
		PartitionStrategy Strategy

		// By default, messages and errors from the subscribed topics and partitions are all multiplexed and
		// made available through the consumer's Messages() and Errors() channels.
		//
		// Users who require low-level access can enable ConsumerModePartitions where individual partitions
		// are exposed on the Partitions() channel. Messages and errors must then be consumed on the partitions
		// themselves.
		Mode ConsumerMode

		Offsets struct {
			Retry struct {
				// The numer retries when committing offsets (defaults to 3).
				Max int
			}
			Synchronization struct {
				// The duration allowed for other clients to commit their offsets before resumption in this client, e.g. during a rebalance
				// NewConfig sets this to the Consumer.MaxProcessingTime duration of the Sarama configuration
				DwellTime time.Duration
			}
		}

		Session struct {
			// The allowed session timeout for registered consumers (defaults to 30s).
			// Must be within the allowed server range.
			Timeout time.Duration
		}

		Heartbeat struct {
			// Interval between each heartbeat (defaults to 3s). It should be no more
			// than 1/3rd of the Group.Session.Timout setting
			Interval time.Duration
		}

		// Return specifies which group channels will be populated. If they are set to true,
		// you must read from the respective channels to prevent deadlock.
		Return struct {
			// If enabled, rebalance notification will be returned on the
			// Notifications channel (default disabled).
			Notifications bool
		}

		Topics struct {
			// An additional whitelist of topics to subscribe to.
			Whitelist *regexp.Regexp
			// An additional blacklist of topics to avoid. If set, this will precede over
			// the Whitelist setting.
			Blacklist *regexp.Regexp
		}

		Member struct {
			// Custom metadata to include when joining the group. The user data for all joined members
			// can be retrieved by sending a DescribeGroupRequest to the broker that is the
			// coordinator for the group.
			UserData []byte
		}
	}
}

// NewConfig returns a new configuration instance with sane defaults.
func NewConfig() *Config {
	c := &Config{
		Config: *sarama.NewConfig(),
	}
	c.Group.PartitionStrategy = StrategyRange
	c.Group.Offsets.Retry.Max = 3
	c.Group.Offsets.Synchronization.DwellTime = c.Consumer.MaxProcessingTime
	c.Group.Session.Timeout = 30 * time.Second
	c.Group.Heartbeat.Interval = 3 * time.Second
	c.Config.Version = minVersion
	return c
}

// Validate checks a Config instance. It will return a
// sarama.ConfigurationError if the specified values don't make sense.
func (c *Config) Validate() error {
	if c.Group.Heartbeat.Interval%time.Millisecond != 0 {
		sarama.Logger.Println("Group.Heartbeat.Interval only supports millisecond precision; nanoseconds will be truncated.")
	}
	if c.Group.Session.Timeout%time.Millisecond != 0 {
		sarama.Logger.Println("Group.Session.Timeout only supports millisecond precision; nanoseconds will be truncated.")
	}
	if c.Group.PartitionStrategy != StrategyRange && c.Group.PartitionStrategy != StrategyRoundRobin {
		sarama.Logger.Println("Group.PartitionStrategy is not supported; range will be assumed.")
	}
	if !c.Version.IsAtLeast(minVersion) {
		sarama.Logger.Println("Version is not supported; 0.9. will be assumed.")
		c.Version = minVersion
	}
	if err := c.Config.Validate(); err != nil {
		return err
	}

	// validate the Group values
	switch {
	case c.Group.Offsets.Retry.Max < 0:
		return sarama.ConfigurationError("Group.Offsets.Retry.Max must be >= 0")
	case c.Group.Offsets.Synchronization.DwellTime <= 0:
		return sarama.ConfigurationError("Group.Offsets.Synchronization.DwellTime must be > 0")
	case c.Group.Offsets.Synchronization.DwellTime > 10*time.Minute:
		return sarama.ConfigurationError("Group.Offsets.Synchronization.DwellTime must be <= 10m")
	case c.Group.Heartbeat.Interval <= 0:
		return sarama.ConfigurationError("Group.Heartbeat.Interval must be > 0")
	case c.Group.Session.Timeout <= 0:
		return sarama.ConfigurationError("Group.Session.Timeout must be > 0")
	case !c.Metadata.Full && c.Group.Topics.Whitelist != nil:
		return sarama.ConfigurationError("Metadata.Full must be enabled when Group.Topics.Whitelist is used")
	case !c.Metadata.Full && c.Group.Topics.Blacklist != nil:
		return sarama.ConfigurationError("Metadata.Full must be enabled when Group.Topics.Blacklist is used")
	}

	// ensure offset is correct
	switch c.Consumer.Offsets.Initial {
	case sarama.OffsetOldest, sarama.OffsetNewest:
	default:
		return sarama.ConfigurationError("Consumer.Offsets.Initial must be either OffsetOldest or OffsetNewest")
	}

	return nil
}
<commit_msg>Update config.go to correct typos (#266)<commit_after>package cluster

import (
	"regexp"
	"time"

	"github.com/Shopify/sarama"
)

var minVersion = sarama.V0_9_0_0

type ConsumerMode uint8

const (
	ConsumerModeMultiplex ConsumerMode = iota
	ConsumerModePartitions
)

// Config extends sarama.Config with Group specific namespace
type Config struct {
	sarama.Config

	// Group is the namespace for group management properties
	Group struct {

		// The strategy to use for the allocation of partitions to consumers (defaults to StrategyRange)
		PartitionStrategy Strategy

		// By default, messages and errors from the subscribed topics and partitions are all multiplexed and
		// made available through the consumer's Messages() and Errors() channels.
		//
		// Users who require low-level access can enable ConsumerModePartitions where individual partitions
		// are exposed on the Partitions() channel. Messages and errors must then be consumed on the partitions
		// themselves.
		Mode ConsumerMode

		Offsets struct {
			Retry struct {
				// The number retries when committing offsets (defaults to 3).
				Max int
			}
			Synchronization struct {
				// The duration allowed for other clients to commit their offsets before resumption in this client, e.g. during a rebalance
				// NewConfig sets this to the Consumer.MaxProcessingTime duration of the Sarama configuration
				DwellTime time.Duration
			}
		}

		Session struct {
			// The allowed session timeout for registered consumers (defaults to 30s).
			// Must be within the allowed server range.
			Timeout time.Duration
		}

		Heartbeat struct {
			// Interval between each heartbeat (defaults to 3s). It should be no more
			// than 1/3rd of the Group.Session.Timeout setting
			Interval time.Duration
		}

		// Return specifies which group channels will be populated. If they are set to true,
		// you must read from the respective channels to prevent deadlock.
		Return struct {
			// If enabled, rebalance notification will be returned on the
			// Notifications channel (default disabled).
			Notifications bool
		}

		Topics struct {
			// An additional whitelist of topics to subscribe to.
			Whitelist *regexp.Regexp
			// An additional blacklist of topics to avoid. If set, this will precede over
			// the Whitelist setting.
			Blacklist *regexp.Regexp
		}

		Member struct {
			// Custom metadata to include when joining the group. The user data for all joined members
			// can be retrieved by sending a DescribeGroupRequest to the broker that is the
			// coordinator for the group.
			UserData []byte
		}
	}
}

// NewConfig returns a new configuration instance with sane defaults.
func NewConfig() *Config {
	c := &Config{
		Config: *sarama.NewConfig(),
	}
	c.Group.PartitionStrategy = StrategyRange
	c.Group.Offsets.Retry.Max = 3
	c.Group.Offsets.Synchronization.DwellTime = c.Consumer.MaxProcessingTime
	c.Group.Session.Timeout = 30 * time.Second
	c.Group.Heartbeat.Interval = 3 * time.Second
	c.Config.Version = minVersion
	return c
}

// Validate checks a Config instance. It will return a
// sarama.ConfigurationError if the specified values don't make sense.
func (c *Config) Validate() error {
	if c.Group.Heartbeat.Interval%time.Millisecond != 0 {
		sarama.Logger.Println("Group.Heartbeat.Interval only supports millisecond precision; nanoseconds will be truncated.")
	}
	if c.Group.Session.Timeout%time.Millisecond != 0 {
		sarama.Logger.Println("Group.Session.Timeout only supports millisecond precision; nanoseconds will be truncated.")
	}
	if c.Group.PartitionStrategy != StrategyRange && c.Group.PartitionStrategy != StrategyRoundRobin {
		sarama.Logger.Println("Group.PartitionStrategy is not supported; range will be assumed.")
	}
	if !c.Version.IsAtLeast(minVersion) {
		sarama.Logger.Println("Version is not supported; 0.9. will be assumed.")
		c.Version = minVersion
	}
	if err := c.Config.Validate(); err != nil {
		return err
	}

	// validate the Group values
	switch {
	case c.Group.Offsets.Retry.Max < 0:
		return sarama.ConfigurationError("Group.Offsets.Retry.Max must be >= 0")
	case c.Group.Offsets.Synchronization.DwellTime <= 0:
		return sarama.ConfigurationError("Group.Offsets.Synchronization.DwellTime must be > 0")
	case c.Group.Offsets.Synchronization.DwellTime > 10*time.Minute:
		return sarama.ConfigurationError("Group.Offsets.Synchronization.DwellTime must be <= 10m")
	case c.Group.Heartbeat.Interval <= 0:
		return sarama.ConfigurationError("Group.Heartbeat.Interval must be > 0")
	case c.Group.Session.Timeout <= 0:
		return sarama.ConfigurationError("Group.Session.Timeout must be > 0")
	case !c.Metadata.Full && c.Group.Topics.Whitelist != nil:
		return sarama.ConfigurationError("Metadata.Full must be enabled when Group.Topics.Whitelist is used")
	case !c.Metadata.Full && c.Group.Topics.Blacklist != nil:
		return sarama.ConfigurationError("Metadata.Full must be enabled when Group.Topics.Blacklist is used")
	}

	// ensure offset is correct
	switch c.Consumer.Offsets.Initial {
	case sarama.OffsetOldest, sarama.OffsetNewest:
	default:
		return sarama.ConfigurationError("Consumer.Offsets.Initial must be either OffsetOldest or OffsetNewest")
	}

	return nil
}
<|endoftext|>