<commit_before>package lfsapi

import (
	"context"
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/git-lfs/git-lfs/config"
	"github.com/git-lfs/git-lfs/errors"
	"github.com/git-lfs/git-lfs/tools"
	"github.com/rubyist/tracerx"
)

var UserAgent = "git-lfs"

const MediaType = "application/vnd.git-lfs+json; charset=utf-8"

func (c *Client) NewRequest(method string, e Endpoint, suffix string, body interface{}) (*http.Request, error) {
	sshRes, err := c.SSH.Resolve(e, method)
	if err != nil {
		tracerx.Printf("ssh: %s failed, error: %s, message: %s",
			e.SshUserAndHost, err.Error(), sshRes.Message,
		)

		if len(sshRes.Message) > 0 {
			return nil, errors.Wrap(err, sshRes.Message)
		}
		return nil, err
	}

	prefix := e.Url
	if len(sshRes.Href) > 0 {
		prefix = sshRes.Href
	}

	req, err := http.NewRequest(method, joinURL(prefix, suffix), nil)
	if err != nil {
		return req, err
	}

	for key, value := range sshRes.Header {
		req.Header.Set(key, value)
	}
	req.Header.Set("Accept", MediaType)

	if body != nil {
		if merr := MarshalToRequest(req, body); merr != nil {
			return req, merr
		}
		req.Header.Set("Content-Type", MediaType)
	}

	return req, err
}

const slash = "/"

func joinURL(prefix, suffix string) string {
	if strings.HasSuffix(prefix, slash) {
		return prefix + suffix
	}
	return prefix + slash + suffix
}

func (c *Client) Do(req *http.Request) (*http.Response, error) {
	req.Header = c.extraHeadersFor(req)
	req.Header.Set("User-Agent", UserAgent)

	res, err := c.doWithRedirects(c.httpClient(req.Host), req, nil)
	if err != nil {
		return res, err
	}

	return res, c.handleResponse(res)
}

// Close closes any resources that this client opened.
func (c *Client) Close() error {
	return c.httpLogger.Close()
}

func (c *Client) extraHeadersFor(req *http.Request) http.Header {
	copy := make(http.Header, len(req.Header))
	for k, vs := range req.Header {
		copy[k] = vs
	}

	for k, vs := range c.extraHeaders(req.URL) {
		for _, v := range vs {
			copy[k] = append(copy[k], v)
		}
	}
	return copy
}

func (c *Client) extraHeaders(u *url.URL) map[string][]string {
	hdrs := c.uc.GetAll("http", u.String(), "extraHeader")
	m := make(map[string][]string, len(hdrs))

	for _, hdr := range hdrs {
		parts := strings.SplitN(hdr, ":", 2)
		if len(parts) < 2 {
			continue
		}

		k, v := parts[0], strings.TrimSpace(parts[1])

		m[k] = append(m[k], v)
	}
	return m
}

func (c *Client) doWithRedirects(cli *http.Client, req *http.Request, via []*http.Request) (*http.Response, error) {
	tracedReq, err := c.traceRequest(req)
	if err != nil {
		return nil, err
	}

	res, err := cli.Do(req)
	if err != nil {
		c.traceResponse(req, tracedReq, nil)
		return res, err
	}

	c.traceResponse(req, tracedReq, res)

	if res.StatusCode != 307 {
		return res, err
	}

	redirectTo := res.Header.Get("Location")
	locurl, err := url.Parse(redirectTo)
	if err == nil && !locurl.IsAbs() {
		locurl = req.URL.ResolveReference(locurl)
		redirectTo = locurl.String()
	}

	via = append(via, req)
	if len(via) >= 3 {
		return res, errors.New("too many redirects")
	}

	redirectedReq, err := newRequestForRetry(req, redirectTo)
	if err != nil {
		return res, err
	}

	return c.doWithRedirects(cli, redirectedReq, via)
}

func (c *Client) httpClient(host string) *http.Client {
	c.clientMu.Lock()
	defer c.clientMu.Unlock()

	if c.gitEnv == nil {
		c.gitEnv = make(TestEnv)
	}

	if c.osEnv == nil {
		c.osEnv = make(TestEnv)
	}

	if c.hostClients == nil {
		c.hostClients = make(map[string]*http.Client)
	}

	if client, ok := c.hostClients[host]; ok {
		return client
	}

	concurrentTransfers := c.ConcurrentTransfers
	if concurrentTransfers < 1 {
		concurrentTransfers = 3
	}

	dialtime := c.DialTimeout
	if dialtime < 1 {
		dialtime = 30
	}

	keepalivetime := c.KeepaliveTimeout
	if keepalivetime < 1 {
		keepalivetime = 1800
	}

	tlstime := c.TLSTimeout
	if tlstime < 1 {
		tlstime = 30
	}

	activityTimeout := 10
	if v, ok := c.uc.Get("lfs", fmt.Sprintf("https://%v", host), "activitytimeout"); ok {
		if i, err := strconv.Atoi(v); err == nil {
			activityTimeout = tools.MaxInt(i, 1)
		}
	}
	activityDuration := time.Duration(activityTimeout) * time.Second

	dialer := &net.Dialer{
		Timeout:   time.Duration(dialtime) * time.Second,
		KeepAlive: time.Duration(keepalivetime) * time.Second,
		DualStack: true,
	}

	tr := &http.Transport{
		Proxy: proxyFromClient(c),
		DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
			c, err := dialer.DialContext(ctx, network, addr)
			if c == nil {
				return c, err
			}
			if tc, ok := c.(*net.TCPConn); ok {
				tc.SetKeepAlive(true)
				tc.SetKeepAlivePeriod(dialer.KeepAlive)
			}
			return &deadlineConn{Timeout: activityDuration, Conn: c}, err
		},
		TLSHandshakeTimeout: time.Duration(tlstime) * time.Second,
		MaxIdleConnsPerHost: concurrentTransfers,
	}

	tr.TLSClientConfig = &tls.Config{}

	if isClientCertEnabledForHost(c, host) {
		tracerx.Printf("http: client cert for %s", host)
		tr.TLSClientConfig.Certificates = []tls.Certificate{getClientCertForHost(c, host)}
		tr.TLSClientConfig.BuildNameToCertificate()
	}

	if isCertVerificationDisabledForHost(c, host) {
		tr.TLSClientConfig.InsecureSkipVerify = true
	} else {
		tr.TLSClientConfig.RootCAs = getRootCAsForHost(c, host)
	}

	httpClient := &http.Client{
		Transport: tr,
		CheckRedirect: func(*http.Request, []*http.Request) error {
			return http.ErrUseLastResponse
		},
	}

	c.hostClients[host] = httpClient
	if c.VerboseOut == nil {
		c.VerboseOut = os.Stderr
	}

	return httpClient
}

func (c *Client) CurrentUser() (string, string) {
	userName, _ := c.gitEnv.Get("user.name")
	userEmail, _ := c.gitEnv.Get("user.email")
	return userName, userEmail
}

func newRequestForRetry(req *http.Request, location string) (*http.Request, error) {
	newReq, err := http.NewRequest(req.Method, location, nil)
	if err != nil {
		return nil, err
	}

	for key := range req.Header {
		if key == "Authorization" {
			if req.URL.Scheme != newReq.URL.Scheme || req.URL.Host != newReq.URL.Host {
				continue
			}
		}
		newReq.Header.Set(key, req.Header.Get(key))
	}

	oldestURL := strings.SplitN(req.URL.String(), "?", 2)[0]
	newURL := strings.SplitN(newReq.URL.String(), "?", 2)[0]
	tracerx.Printf("api: redirect %s %s to %s", req.Method, oldestURL, newURL)

	newReq.Body = req.Body
	newReq.ContentLength = req.ContentLength
	return newReq, nil
}

type deadlineConn struct {
	Timeout time.Duration
	net.Conn
}

func (c *deadlineConn) Read(b []byte) (int, error) {
	if err := c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return 0, err
	}
	return c.Conn.Read(b)
}

func (c *deadlineConn) Write(b []byte) (int, error) {
	if err := c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return 0, err
	}

	return c.Conn.Write(b)
}

func init() {
	UserAgent = config.VersionDesc
}
<commit_msg>disable activity timeout if activitytimeout=0<commit_after>package lfsapi

import (
	"context"
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/git-lfs/git-lfs/config"
	"github.com/git-lfs/git-lfs/errors"
	"github.com/rubyist/tracerx"
)

var UserAgent = "git-lfs"

const MediaType = "application/vnd.git-lfs+json; charset=utf-8"

func (c *Client) NewRequest(method string, e Endpoint, suffix string, body interface{}) (*http.Request, error) {
	sshRes, err := c.SSH.Resolve(e, method)
	if err != nil {
		tracerx.Printf("ssh: %s failed, error: %s, message: %s",
			e.SshUserAndHost, err.Error(), sshRes.Message,
		)

		if len(sshRes.Message) > 0 {
			return nil, errors.Wrap(err, sshRes.Message)
		}
		return nil, err
	}

	prefix := e.Url
	if len(sshRes.Href) > 0 {
		prefix = sshRes.Href
	}

	req, err := http.NewRequest(method, joinURL(prefix, suffix), nil)
	if err != nil {
		return req, err
	}

	for key, value := range sshRes.Header {
		req.Header.Set(key, value)
	}
	req.Header.Set("Accept", MediaType)

	if body != nil {
		if merr := MarshalToRequest(req, body); merr != nil {
			return req, merr
		}
		req.Header.Set("Content-Type", MediaType)
	}

	return req, err
}

const slash = "/"

func joinURL(prefix, suffix string) string {
	if strings.HasSuffix(prefix, slash) {
		return prefix + suffix
	}
	return prefix + slash + suffix
}

func (c *Client) Do(req *http.Request) (*http.Response, error) {
	req.Header = c.extraHeadersFor(req)
	req.Header.Set("User-Agent", UserAgent)

	res, err := c.doWithRedirects(c.httpClient(req.Host), req, nil)
	if err != nil {
		return res, err
	}

	return res, c.handleResponse(res)
}

// Close closes any resources that this client opened.
func (c *Client) Close() error {
	return c.httpLogger.Close()
}

func (c *Client) extraHeadersFor(req *http.Request) http.Header {
	copy := make(http.Header, len(req.Header))
	for k, vs := range req.Header {
		copy[k] = vs
	}

	for k, vs := range c.extraHeaders(req.URL) {
		for _, v := range vs {
			copy[k] = append(copy[k], v)
		}
	}
	return copy
}

func (c *Client) extraHeaders(u *url.URL) map[string][]string {
	hdrs := c.uc.GetAll("http", u.String(), "extraHeader")
	m := make(map[string][]string, len(hdrs))

	for _, hdr := range hdrs {
		parts := strings.SplitN(hdr, ":", 2)
		if len(parts) < 2 {
			continue
		}

		k, v := parts[0], strings.TrimSpace(parts[1])

		m[k] = append(m[k], v)
	}
	return m
}

func (c *Client) doWithRedirects(cli *http.Client, req *http.Request, via []*http.Request) (*http.Response, error) {
	tracedReq, err := c.traceRequest(req)
	if err != nil {
		return nil, err
	}

	res, err := cli.Do(req)
	if err != nil {
		c.traceResponse(req, tracedReq, nil)
		return res, err
	}

	c.traceResponse(req, tracedReq, res)

	if res.StatusCode != 307 {
		return res, err
	}

	redirectTo := res.Header.Get("Location")
	locurl, err := url.Parse(redirectTo)
	if err == nil && !locurl.IsAbs() {
		locurl = req.URL.ResolveReference(locurl)
		redirectTo = locurl.String()
	}

	via = append(via, req)
	if len(via) >= 3 {
		return res, errors.New("too many redirects")
	}

	redirectedReq, err := newRequestForRetry(req, redirectTo)
	if err != nil {
		return res, err
	}

	return c.doWithRedirects(cli, redirectedReq, via)
}

func (c *Client) httpClient(host string) *http.Client {
	c.clientMu.Lock()
	defer c.clientMu.Unlock()

	if c.gitEnv == nil {
		c.gitEnv = make(TestEnv)
	}

	if c.osEnv == nil {
		c.osEnv = make(TestEnv)
	}

	if c.hostClients == nil {
		c.hostClients = make(map[string]*http.Client)
	}

	if client, ok := c.hostClients[host]; ok {
		return client
	}

	concurrentTransfers := c.ConcurrentTransfers
	if concurrentTransfers < 1 {
		concurrentTransfers = 3
	}

	dialtime := c.DialTimeout
	if dialtime < 1 {
		dialtime = 30
	}

	keepalivetime := c.KeepaliveTimeout
	if keepalivetime < 1 {
		keepalivetime = 1800
	}

	tlstime := c.TLSTimeout
	if tlstime < 1 {
		tlstime = 30
	}

	tr := &http.Transport{
		Proxy:               proxyFromClient(c),
		TLSHandshakeTimeout: time.Duration(tlstime) * time.Second,
		MaxIdleConnsPerHost: concurrentTransfers,
	}

	activityTimeout := 10
	if v, ok := c.uc.Get("lfs", fmt.Sprintf("https://%v", host), "activitytimeout"); ok {
		if i, err := strconv.Atoi(v); err == nil {
			activityTimeout = i
		} else {
			activityTimeout = 0
		}
	}

	dialer := &net.Dialer{
		Timeout:   time.Duration(dialtime) * time.Second,
		KeepAlive: time.Duration(keepalivetime) * time.Second,
		DualStack: true,
	}

	if activityTimeout > 0 {
		activityDuration := time.Duration(activityTimeout) * time.Second
		tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
			c, err := dialer.DialContext(ctx, network, addr)
			if c == nil {
				return c, err
			}
			if tc, ok := c.(*net.TCPConn); ok {
				tc.SetKeepAlive(true)
				tc.SetKeepAlivePeriod(dialer.KeepAlive)
			}
			return &deadlineConn{Timeout: activityDuration, Conn: c}, err
		}
	} else {
		tr.DialContext = dialer.DialContext
	}

	tr.TLSClientConfig = &tls.Config{}

	if isClientCertEnabledForHost(c, host) {
		tracerx.Printf("http: client cert for %s", host)
		tr.TLSClientConfig.Certificates = []tls.Certificate{getClientCertForHost(c, host)}
		tr.TLSClientConfig.BuildNameToCertificate()
	}

	if isCertVerificationDisabledForHost(c, host) {
		tr.TLSClientConfig.InsecureSkipVerify = true
	} else {
		tr.TLSClientConfig.RootCAs = getRootCAsForHost(c, host)
	}

	httpClient := &http.Client{
		Transport: tr,
		CheckRedirect: func(*http.Request, []*http.Request) error {
			return http.ErrUseLastResponse
		},
	}

	c.hostClients[host] = httpClient
	if c.VerboseOut == nil {
		c.VerboseOut = os.Stderr
	}

	return httpClient
}

func (c *Client) CurrentUser() (string, string) {
	userName, _ := c.gitEnv.Get("user.name")
	userEmail, _ := c.gitEnv.Get("user.email")
	return userName, userEmail
}

func newRequestForRetry(req *http.Request, location string) (*http.Request, error) {
	newReq, err := http.NewRequest(req.Method, location, nil)
	if err != nil {
		return nil, err
	}

	for key := range req.Header {
		if key == "Authorization" {
			if req.URL.Scheme != newReq.URL.Scheme || req.URL.Host != newReq.URL.Host {
				continue
			}
		}
		newReq.Header.Set(key, req.Header.Get(key))
	}

	oldestURL := strings.SplitN(req.URL.String(), "?", 2)[0]
	newURL := strings.SplitN(newReq.URL.String(), "?", 2)[0]
	tracerx.Printf("api: redirect %s %s to %s", req.Method, oldestURL, newURL)

	newReq.Body = req.Body
	newReq.ContentLength = req.ContentLength
	return newReq, nil
}

type deadlineConn struct {
	Timeout time.Duration
	net.Conn
}

func (c *deadlineConn) Read(b []byte) (int, error) {
	if err := c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return 0, err
	}
	return c.Conn.Read(b)
}

func (c *deadlineConn) Write(b []byte) (int, error) {
	if err := c.Conn.SetDeadline(time.Now().Add(c.Timeout)); err != nil {
		return 0, err
	}

	return c.Conn.Write(b)
}

func init() {
	UserAgent = config.VersionDesc
}
<|endoftext|>


<commit_before>// Example of creating a web based application purely using
// the net/http package to display weather information and
// Twitter Bootstrap so it doesn't look like it's '92.
//
// To start the app, run:
//    go run weatherweb.go
//
// Accessible via:  http://localhost:8888/here
package main

import (
	"encoding/json"
	"html/template"
	"os"

	owm "github.com/briandowns/openweathermap"
	//	"io/ioutil"
	"log"
	"net/http"
)

// URL is a constant that contains where to find the IP locale info
const URL = "http://ip-api.com/json"

// Data will hold the result of the query to get the IP
// address of the caller.
type Data struct {
	Status      string  `json:"status"`
	Country     string  `json:"country"`
	CountryCode string  `json:"countryCode"`
	Region      string  `json:"region"`
	RegionName  string  `json:"regionName"`
	City        string  `json:"city"`
	Zip         string  `json:"zip"`
	Lat         float64 `json:"lat"`
	Lon         float64 `json:"lon"`
	Timezone    string  `json:"timezone"`
	ISP         string  `json:"isp"`
	ORG         string  `json:"org"`
	AS          string  `json:"as"`
	Message     string  `json:"message"`
	Query       string  `json:"query"`
}

// getLocation will get the location details for where this
// application has been run from.
func getLocation() (*Data, error) {
	response, err := http.Get(URL)
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()
	r := &Data{}
	if err = json.NewDecoder(response.Body).Decode(&r); err != nil {
		return nil, err
	}
	return r, nil
}

// getCurrent gets the current weather for the provided location in
// the units provided.
func getCurrent(l, u, lang string) *owm.CurrentWeatherData {
	w, err := owm.NewCurrent(u, lang, os.Getenv("OWM_API_KEY")) // Create the instance with the given unit
	if err != nil {
		log.Fatal(err)
	}
	w.CurrentByName(l) // Get the actual data for the given location
	return w
}

// hereHandler will take are of requests coming in for the "/here" route.
func hereHandler(w http.ResponseWriter, r *http.Request) {
	location, err := getLocation()
	if err != nil {
		log.Fatal(err)
	}
	wd := getCurrent(location.City, "F", "en")

	// Process our template
	t, err := template.ParseFiles("templates/here.html")
	if err != nil {
		log.Fatal(err)
	}
	// We're doin' naughty things below... Ignoring icon file size and possible errors.
	_, _ = owm.RetrieveIcon("static/img", wd.Weather[0].Icon+".png")

	// Write out the template with the given data
	t.Execute(w, wd)
}

// Run the app
func main() {
	http.HandleFunc("/here", hereHandler)
	// Make sure we can serve our icon files once retrieved
	http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, r.URL.Path[1:])
	})
	http.ListenAndServe(":8888", nil)
}
<commit_msg>Reorder imports<commit_after>// Example of creating a web based application purely using
// the net/http package to display weather information and
// Twitter Bootstrap so it doesn't look like it's '92.
//
// To start the app, run:
//    go run weatherweb.go
//
// Accessible via:  http://localhost:8888/here
package main

import (
	"encoding/json"
	"html/template"

	owm "github.com/briandowns/openweathermap"
	//	"io/ioutil"
	"log"
	"net/http"
	"os"
)

// URL is a constant that contains where to find the IP locale info
const URL = "http://ip-api.com/json"

// Data will hold the result of the query to get the IP
// address of the caller.
type Data struct {
	Status      string  `json:"status"`
	Country     string  `json:"country"`
	CountryCode string  `json:"countryCode"`
	Region      string  `json:"region"`
	RegionName  string  `json:"regionName"`
	City        string  `json:"city"`
	Zip         string  `json:"zip"`
	Lat         float64 `json:"lat"`
	Lon         float64 `json:"lon"`
	Timezone    string  `json:"timezone"`
	ISP         string  `json:"isp"`
	ORG         string  `json:"org"`
	AS          string  `json:"as"`
	Message     string  `json:"message"`
	Query       string  `json:"query"`
}

// getLocation will get the location details for where this
// application has been run from.
func getLocation() (*Data, error) {
	response, err := http.Get(URL)
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()
	r := &Data{}
	if err = json.NewDecoder(response.Body).Decode(&r); err != nil {
		return nil, err
	}
	return r, nil
}

// getCurrent gets the current weather for the provided location in
// the units provided.
func getCurrent(l, u, lang string) *owm.CurrentWeatherData {
	w, err := owm.NewCurrent(u, lang, os.Getenv("OWM_API_KEY")) // Create the instance with the given unit
	if err != nil {
		log.Fatal(err)
	}
	w.CurrentByName(l) // Get the actual data for the given location
	return w
}

// hereHandler will take are of requests coming in for the "/here" route.
func hereHandler(w http.ResponseWriter, r *http.Request) {
	location, err := getLocation()
	if err != nil {
		log.Fatal(err)
	}
	wd := getCurrent(location.City, "F", "en")

	// Process our template
	t, err := template.ParseFiles("templates/here.html")
	if err != nil {
		log.Fatal(err)
	}
	// We're doin' naughty things below... Ignoring icon file size and possible errors.
	_, _ = owm.RetrieveIcon("static/img", wd.Weather[0].Icon+".png")

	// Write out the template with the given data
	t.Execute(w, wd)
}

// Run the app
func main() {
	http.HandleFunc("/here", hereHandler)
	// Make sure we can serve our icon files once retrieved
	http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, r.URL.Path[1:])
	})
	http.ListenAndServe(":8888", nil)
}
<|endoftext|>


<commit_before>package jd

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"strings"
)

func ReadDiffFile(filename string) (Diff, error) {
	bytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return readDiff(string(bytes))
}

func ReadDiffString(s string) (Diff, error) {
	return readDiff(s)
}

func readDiff(s string) (Diff, error) {
	diff := Diff{}
	diffLines := strings.Split(s, "\n")
	const (
		INIT = iota
		AT   = iota
		OLD  = iota
		NEW  = iota
	)
	var de DiffElement
	var state = INIT
	for i, dl := range diffLines {
		if len(dl) == 0 {
			continue
		}
		header := dl[:1]
		// Validate state transistion.
		switch state {
		case INIT:
			if header != "@" {
				return errorAt(i, "Unexpected %c. Expecteding @.", dl[0])
			}
		case AT:
			if header != "-" && header != "+" {
				return errorAt(i, "Unexpected %c. Expecting - or +.", dl[0])
			}
		case OLD:
			if header != "@" && header != "-" && header != "+" {
				return errorAt(i, "Unexpected %c. Expecting + or @.", dl[0])
			}
		case NEW:
			if header != "+" && header != "@" {
				return errorAt(i, "Unexpected %c. Expecteding + or @.", dl[0])
			}
		}
		// Process line.
		switch header {
		case "@":
			if state != INIT {
				// Save the previous diff element.
				errString := checkDiffElement(de)
				if errString != "" {
					return errorAt(i, errString)
				}
				diff = append(diff, de)
			}
			p, err := ReadJsonString(dl[1:])
			if err != nil {
				return errorAt(i, "Invalid path. %v", err.Error())
			}
			pa, ok := p.(jsonArray)
			if !ok {
				return errorAt(i, "Invalid path. Want JSON list. Got %T.", p)
			}
			de = DiffElement{
				Path:      path(pa).clone(),
				OldValues: []JsonNode{},
				NewValues: []JsonNode{},
			}
			state = AT
		case "-":
			v, err := ReadJsonString(dl[1:])
			if err != nil {
				return errorAt(i, "Invalid value. %v", err.Error())
			}
			de.OldValues = append(de.OldValues, v)
			state = OLD
		case "+":
			v, err := ReadJsonString(dl[1:])
			if err != nil {
				return errorAt(i, "Invalid value. %v", err.Error())
			}
			de.NewValues = append(de.NewValues, v)
			state = NEW
		default:
			errorAt(i, "Unexpected %v.", dl[0])
		}
	}
	if state == AT {
		// @ is not a valid terminal state.
		return errorAt(len(diffLines), "Unexpected end of diff. Expecting - or +.")
	}
	if state != INIT {
		// Save the last diff element.
		// Empty string diff is valid so state could be INIT
		errString := checkDiffElement(de)
		if errString != "" {
			return errorAt(len(diffLines), errString)
		}
		diff = append(diff, de)
	}
	return diff, nil
}

func checkDiffElement(de DiffElement) string {
	if len(de.NewValues) > 1 || len(de.OldValues) > 1 {
		// Must be a set.
		emptyObject, _ := NewJsonNode(map[string]interface{}{})
		if len(de.Path) == 0 || !de.Path[len(de.Path)-1].Equals(emptyObject) {
			return "Expected path to end with {} for sets."
		}
	}
	return ""
}

func errorAt(lineZeroIndex int, err string, i ...interface{}) (Diff, error) {
	line := lineZeroIndex + 1
	e := fmt.Sprintf(err, i...)
	return nil, fmt.Errorf("Invalid diff at line %v. %v", line, e)
}

func ReadPatchFile(filename string) (Diff, error) {
	bytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return ReadPatchString(string(bytes))
}

func ReadPatchString(s string) (Diff, error) {
	var patch []patchElement
	err := json.Unmarshal([]byte(s), &patch)
	if err != nil {
		return nil, err
	}
	var diff Diff
	var element DiffElement
	for {
		if len(patch) == 0 {
			return diff, nil
		}
		element, patch, err = readPatchDiffElement(patch)
		if err != nil {
			return nil, err
		}
		diff = append(diff, element)
	}
}

func readPatchDiffElement(patch []patchElement) (DiffElement, []patchElement, error) {
	d := DiffElement{}
	if len(patch) == 0 {
		return d, nil, fmt.Errorf("Unexpected end of JSON Patch.")
	}
	p := patch[0]
	var err error
	switch p.Op {
	case "test":
		// Read path.
		d.Path, err = readPointer(p.Path)
		if err != nil {
			return d, nil, err
		}
		// Read value to test and remove.
		testValue, err := NewJsonNode(p.Value)
		if err != nil {
			return d, nil, err
		}
		d.OldValues = []JsonNode{testValue}
		patch = patch[1:]
		// Validate test and remove are paired because jd remove is strict.
		if len(patch) == 0 || patch[0].Op != "remove" {
			return d, nil, fmt.Errorf("JSON Patch test op must be followed by a remove op.")
		}
		if patch[0].Path != p.Path {
			return d, nil, fmt.Errorf("JSON Patch remove op must have the same path as test op.")
		}
		removeValue, err := NewJsonNode(patch[0].Value)
		if err != nil {
			return d, nil, err
		}
		if !testValue.Equals(removeValue) {
			return d, nil, fmt.Errorf("JSON Patch remove op must have the same value as test op.")
		}
		return d, patch[1:], nil
	case "add":
		d.Path, err = readPointer(p.Path)
		if err != nil {
			return d, nil, err
		}
		addValue, err := NewJsonNode(p.Value)
		if err != nil {
			return d, nil, err
		}
		d.NewValues = []JsonNode{addValue}
		return d, patch[1:], nil
	default:
		return d, nil, fmt.Errorf("Invalid JSON Patch. Must be test/remove or add ops.")
	}
}

func ReadMergeFile(filename string) (Diff, error) {
	bytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return ReadMergeString(string(bytes))
}

func ReadMergeString(s string) (Diff, error) {
	n, err := ReadJsonString(s)
	if err != nil {
		return nil, err
	}
	d := Diff{}
	p := []JsonNode{jsonArray{jsonString(MERGE.string())}}
	return readMergeInto(d, p, n), nil
}

func readMergeInto(d Diff, p path, n JsonNode) Diff {
	switch n := n.(type) {
	case jsonObject:
		for k, v := range n {
			d = readMergeInto(d, append(p.clone(), jsonString(k)), v)
		}
	default:
		if isNull(n) {
			n = voidNode{}
		}
		return append(d, DiffElement{
			Path:      p.clone(),
			NewValues: []JsonNode{n},
		})
	}
	return d
}
<commit_msg>Create empty object in merge.<commit_after>package jd

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"strings"
)

func ReadDiffFile(filename string) (Diff, error) {
	bytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return readDiff(string(bytes))
}

func ReadDiffString(s string) (Diff, error) {
	return readDiff(s)
}

func readDiff(s string) (Diff, error) {
	diff := Diff{}
	diffLines := strings.Split(s, "\n")
	const (
		INIT = iota
		AT   = iota
		OLD  = iota
		NEW  = iota
	)
	var de DiffElement
	var state = INIT
	for i, dl := range diffLines {
		if len(dl) == 0 {
			continue
		}
		header := dl[:1]
		// Validate state transistion.
		switch state {
		case INIT:
			if header != "@" {
				return errorAt(i, "Unexpected %c. Expecteding @.", dl[0])
			}
		case AT:
			if header != "-" && header != "+" {
				return errorAt(i, "Unexpected %c. Expecting - or +.", dl[0])
			}
		case OLD:
			if header != "@" && header != "-" && header != "+" {
				return errorAt(i, "Unexpected %c. Expecting + or @.", dl[0])
			}
		case NEW:
			if header != "+" && header != "@" {
				return errorAt(i, "Unexpected %c. Expecteding + or @.", dl[0])
			}
		}
		// Process line.
		switch header {
		case "@":
			if state != INIT {
				// Save the previous diff element.
				errString := checkDiffElement(de)
				if errString != "" {
					return errorAt(i, errString)
				}
				diff = append(diff, de)
			}
			p, err := ReadJsonString(dl[1:])
			if err != nil {
				return errorAt(i, "Invalid path. %v", err.Error())
			}
			pa, ok := p.(jsonArray)
			if !ok {
				return errorAt(i, "Invalid path. Want JSON list. Got %T.", p)
			}
			de = DiffElement{
				Path:      path(pa).clone(),
				OldValues: []JsonNode{},
				NewValues: []JsonNode{},
			}
			state = AT
		case "-":
			v, err := ReadJsonString(dl[1:])
			if err != nil {
				return errorAt(i, "Invalid value. %v", err.Error())
			}
			de.OldValues = append(de.OldValues, v)
			state = OLD
		case "+":
			v, err := ReadJsonString(dl[1:])
			if err != nil {
				return errorAt(i, "Invalid value. %v", err.Error())
			}
			de.NewValues = append(de.NewValues, v)
			state = NEW
		default:
			errorAt(i, "Unexpected %v.", dl[0])
		}
	}
	if state == AT {
		// @ is not a valid terminal state.
		return errorAt(len(diffLines), "Unexpected end of diff. Expecting - or +.")
	}
	if state != INIT {
		// Save the last diff element.
		// Empty string diff is valid so state could be INIT
		errString := checkDiffElement(de)
		if errString != "" {
			return errorAt(len(diffLines), errString)
		}
		diff = append(diff, de)
	}
	return diff, nil
}

func checkDiffElement(de DiffElement) string {
	if len(de.NewValues) > 1 || len(de.OldValues) > 1 {
		// Must be a set.
		emptyObject, _ := NewJsonNode(map[string]interface{}{})
		if len(de.Path) == 0 || !de.Path[len(de.Path)-1].Equals(emptyObject) {
			return "Expected path to end with {} for sets."
		}
	}
	return ""
}

func errorAt(lineZeroIndex int, err string, i ...interface{}) (Diff, error) {
	line := lineZeroIndex + 1
	e := fmt.Sprintf(err, i...)
	return nil, fmt.Errorf("Invalid diff at line %v. %v", line, e)
}

func ReadPatchFile(filename string) (Diff, error) {
	bytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return ReadPatchString(string(bytes))
}

func ReadPatchString(s string) (Diff, error) {
	var patch []patchElement
	err := json.Unmarshal([]byte(s), &patch)
	if err != nil {
		return nil, err
	}
	var diff Diff
	var element DiffElement
	for {
		if len(patch) == 0 {
			return diff, nil
		}
		element, patch, err = readPatchDiffElement(patch)
		if err != nil {
			return nil, err
		}
		diff = append(diff, element)
	}
}

func readPatchDiffElement(patch []patchElement) (DiffElement, []patchElement, error) {
	d := DiffElement{}
	if len(patch) == 0 {
		return d, nil, fmt.Errorf("Unexpected end of JSON Patch.")
	}
	p := patch[0]
	var err error
	switch p.Op {
	case "test":
		// Read path.
		d.Path, err = readPointer(p.Path)
		if err != nil {
			return d, nil, err
		}
		// Read value to test and remove.
		testValue, err := NewJsonNode(p.Value)
		if err != nil {
			return d, nil, err
		}
		d.OldValues = []JsonNode{testValue}
		patch = patch[1:]
		// Validate test and remove are paired because jd remove is strict.
		if len(patch) == 0 || patch[0].Op != "remove" {
			return d, nil, fmt.Errorf("JSON Patch test op must be followed by a remove op.")
		}
		if patch[0].Path != p.Path {
			return d, nil, fmt.Errorf("JSON Patch remove op must have the same path as test op.")
		}
		removeValue, err := NewJsonNode(patch[0].Value)
		if err != nil {
			return d, nil, err
		}
		if !testValue.Equals(removeValue) {
			return d, nil, fmt.Errorf("JSON Patch remove op must have the same value as test op.")
		}
		return d, patch[1:], nil
	case "add":
		d.Path, err = readPointer(p.Path)
		if err != nil {
			return d, nil, err
		}
		addValue, err := NewJsonNode(p.Value)
		if err != nil {
			return d, nil, err
		}
		d.NewValues = []JsonNode{addValue}
		return d, patch[1:], nil
	default:
		return d, nil, fmt.Errorf("Invalid JSON Patch. Must be test/remove or add ops.")
	}
}

func ReadMergeFile(filename string) (Diff, error) {
	bytes, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return ReadMergeString(string(bytes))
}

func ReadMergeString(s string) (Diff, error) {
	n, err := ReadJsonString(s)
	if err != nil {
		return nil, err
	}
	d := Diff{}
	p := []JsonNode{jsonArray{jsonString(MERGE.string())}}
	return readMergeInto(d, p, n), nil
}

func readMergeInto(d Diff, p path, n JsonNode) Diff {
	switch n := n.(type) {
	case jsonObject:
		for k, v := range n {
			d = readMergeInto(d, append(p.clone(), jsonString(k)), v)
		}
		if len(n) == 0 {
			return append(d, DiffElement{
				Path:      p.clone(),
				NewValues: []JsonNode{newJsonObject()},
			})
		}
	default:
		if isNull(n) {
			n = voidNode{}
		}
		return append(d, DiffElement{
			Path:      p.clone(),
			NewValues: []JsonNode{n},
		})
	}
	return d
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/hex"
	"flag"
	"fmt"
	"github.com/ethereum/eth-go"
	"github.com/ethereum/ethchain-go"
	"github.com/ethereum/ethutil-go"
	_ "github.com/ethereum/ethwire-go"
	"log"
	"os"
	"os/signal"
	"runtime"
	"time"
)

const Debug = true

var StartConsole bool
var StartMining bool

func Init() {
	flag.BoolVar(&StartConsole, "c", false, "debug and testing console")
	flag.BoolVar(&StartMining, "m", false, "start dagger mining")

	flag.Parse()
}

// Register interrupt handlers so we can stop the ethereum
func RegisterInterupts(s *eth.Ethereum) {
	// Buffered chan of one is enough
	c := make(chan os.Signal, 1)
	// Notify about interrupts for now
	signal.Notify(c, os.Interrupt)
	go func() {
		for sig := range c {
			fmt.Printf("Shutting down (%v) ... \n", sig)

			s.Stop()
		}
	}()
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	Init()

	//fmt.Printf("%x\n", ethutil.Encode([]interface{}{ethutil.BigPow(2, 36).Bytes()}))

	ethchain.InitFees()
	ethutil.ReadConfig()

	log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver)

	// Instantiated a eth stack
	ethereum, err := eth.New()
	if err != nil {
		log.Println(err)
		return
	}

	if StartConsole {
		err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm)
		// Error is OK if the error is ErrExist
		if err != nil && !os.IsExist(err) {
			log.Panic("Unable to create EXECPATH:", err)
		}

		console := NewConsole(ethereum)
		go console.Start()
	}

	RegisterInterupts(ethereum)

	ethereum.Start()

	if StartMining {
		blockTime := time.Duration(10)
		log.Printf("Dev Test Mining started. Blocks found each %d seconds\n", blockTime)

		// Fake block mining. It broadcasts a new block every 5 seconds
		go func() {
			pow := &ethchain.EasyPow{}
			addr, _ := hex.DecodeString("82c3b0b72cf62f1a9ce97c64da8072efa28225d8")

			for {
				time.Sleep(blockTime * time.Second)

				txs := ethereum.TxPool.Flush()
				block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs)

				nonce := pow.Search(block)
				block.Nonce = nonce

				err := ethereum.BlockManager.ProcessBlockWithState(block, block.State())
				if err != nil {
					log.Println(err)
				} else {
					//log.Println("nonce found:", nonce)
					log.Println("\n+++++++ MINED BLK +++++++\n", block.String())
				}
				//os.Exit(1)

				/*

					block := ethchain.CreateBlock(
						ethereum.BlockManager.BlockChain().CurrentBlock.State().Root,
						ethereum.BlockManager.BlockChain().LastBlockHash,
						"123",
						big.NewInt(1),
						big.NewInt(1),
						"",
						txs)
					err := ethereum.BlockManager.ProcessBlockWithState(block, block.State())
					if err != nil {
						log.Println(err)
					} else {
						//log.Println("\n+++++++ MINED BLK +++++++\n", block.String())
					}
				*/
			}
		}()
	}

	// Wait for shutdown
	ethereum.WaitForShutdown()
}
<commit_msg>upnp test<commit_after>package main

import (
	"encoding/hex"
	"flag"
	"fmt"
	"github.com/ethereum/eth-go"
	"github.com/ethereum/ethchain-go"
	"github.com/ethereum/ethutil-go"
	_ "github.com/ethereum/ethwire-go"
	"log"
	"os"
	"os/signal"
	"runtime"
	"time"
)

const Debug = true

var StartConsole bool
var StartMining bool

func Init() {
	flag.BoolVar(&StartConsole, "c", false, "debug and testing console")
	flag.BoolVar(&StartMining, "m", false, "start dagger mining")

	flag.Parse()
}

// Register interrupt handlers so we can stop the ethereum
func RegisterInterupts(s *eth.Ethereum) {
	// Buffered chan of one is enough
	c := make(chan os.Signal, 1)
	// Notify about interrupts for now
	signal.Notify(c, os.Interrupt)
	go func() {
		for sig := range c {
			fmt.Printf("Shutting down (%v) ... \n", sig)

			s.Stop()
		}
	}()
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	Init()

	ethchain.InitFees()
	ethutil.ReadConfig()

	log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver)

	// Instantiated a eth stack
	ethereum, err := eth.New(eth.CapDefault)
	if err != nil {
		log.Println(err)
		return
	}

	if StartConsole {
		err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm)
		// Error is OK if the error is ErrExist
		if err != nil && !os.IsExist(err) {
			log.Panic("Unable to create EXECPATH:", err)
		}

		console := NewConsole(ethereum)
		go console.Start()
	}

	RegisterInterupts(ethereum)

	ethereum.Start()

	if StartMining {
		blockTime := time.Duration(10)
		log.Printf("Dev Test Mining started. Blocks found each %d seconds\n", blockTime)

		// Fake block mining. It broadcasts a new block every 5 seconds
		go func() {
			pow := &ethchain.EasyPow{}
			addr, _ := hex.DecodeString("82c3b0b72cf62f1a9ce97c64da8072efa28225d8")

			for {
				time.Sleep(blockTime * time.Second)

				txs := ethereum.TxPool.Flush()
				block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs)

				nonce := pow.Search(block)
				block.Nonce = nonce

				err := ethereum.BlockManager.ProcessBlockWithState(block, block.State())
				if err != nil {
					log.Println(err)
				} else {
					//log.Println("nonce found:", nonce)
					log.Println("\n+++++++ MINED BLK +++++++\n", block.String())
				}
				//os.Exit(1)

				/*

					block := ethchain.CreateBlock(
						ethereum.BlockManager.BlockChain().CurrentBlock.State().Root,
						ethereum.BlockManager.BlockChain().LastBlockHash,
						"123",
						big.NewInt(1),
						big.NewInt(1),
						"",
						txs)
					err := ethereum.BlockManager.ProcessBlockWithState(block, block.State())
					if err != nil {
						log.Println(err)
					} else {
						//log.Println("\n+++++++ MINED BLK +++++++\n", block.String())
					}
				*/
			}
		}()
	}

	// Wait for shutdown
	ethereum.WaitForShutdown()
}
<|endoftext|>


<commit_before>/*
The file Package is meant to take care of all asset file opening so that file
access is safe if trying to access a bundled file or a file from the disk
*/
package file

import (
	"bytes"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"
)

// the File interface makes accessing bundled files and os.File consistent
type File interface {
	io.Reader
	io.Writer
	io.Seeker
	io.Closer
}

// Read will read a file at the path specified in total and return a byte
// array of the file contents
func Read(path string) ([]byte, error) {
	path = normalizePath(path)
	zipFile, ok := zipFiles[path]
	if !ok {
		return ioutil.ReadFile(path)
	}

	rc, err := zipFile.Open()
	defer rc.Close()
	if err != nil {
		return nil, err
	}
	return ioutil.ReadAll(rc)
}

// ReadString acts like Read but instead return a string. This is useful in certain
// circumstances.
func ReadString(filename string) string {
	s, err := Read(filename)
	if err != nil {
		panic(err)
	}
	return string(s[:])
}

// NewFileData retreives the file info for the path provided. If the file does
// not exist it will return an error
func NewFileData(filename string) (os.FileInfo, error) {
	return stat(filename)
}

// NewFile will return the file if its bundled or on disk and return a File interface
// for the file and an error if it does not exist. The File interface allows for
// consitent access to disk files and zip files.
func NewFile(path string) (File, error) {
	path = normalizePath(path)
	zipFile, ok := zipFiles[path]
	if !ok {
		return os.Open(path)
	}

	rc, err := zipFile.Open()
	if err != nil {
		return nil, err
	}
	all, err := ioutil.ReadAll(rc)
	if err != nil {
		return nil, err
	}
	return &file{
		ReadCloser: rc,
		data:       all,
		reader:     io.NewSectionReader(bytes.NewReader(all), 0, zipFile.FileInfo().Size()),
	}, nil
}

// CreateDirectory will create all directories in the path given if they do not exist
func CreateDirectory(path string) error {
	return os.MkdirAll(normalizePath(path), os.ModeDir|os.ModePerm)
}

// Exists will return true if the file exists at the path provided and false if
// the file does not exist.
func Exists(filename string) bool {
	info, err := stat(filename)
	return info != nil && err == nil
}

// Remove will delete a file at the given path and return an error if there was
// and issue
func Remove(path string) error {
	return os.Remove(normalizePath(path))
}

// IsDirectory will return true if the path provided is a directory and false
// if the file does not exist or is not a directory.
func IsDirectory(filename string) bool {
	info, err := stat(filename)
	if err != nil {
		return false
	}
	return info.IsDir()
}

// IsFile will return false if file does not exist or is directory. It will return
// true otherwise.
func IsFile(filename string) bool {
	info, err := stat(filename)
	if err != nil {
		return false
	}
	return !info.IsDir()
}

// IsSymLink will return false if the file does not exist or is not a symlink. It
// will return true if the file is a symlink
func IsSymLink(filename string) bool {
	info, err := stat(filename)
	if err != nil {
		return false
	}
	return (info.Mode() & os.ModeSymlink) != 0
}

// GetSize will return the files size in bytes, it will return 0 if the file does
// not exist
func GetSize(filename string) int32 {
	info, err := stat(filename)
	if err != nil {
		return 0
	}
	return int32(info.Size())
}

// GetLastModified will return the time of when the file was last modified, if
// the file does not exist the time will be 0
func GetLastModified(filename string) time.Time {
	info, err := stat(filename)
	if err != nil {
		return time.Time{}
	}
	return info.ModTime()
}

// Ext will return the extention of the file
func Ext(filename string) string {
	return filepath.Ext(normalizePath(filename))
}
<commit_msg>added a function to create a file<commit_after>/*
The file Package is meant to take care of all asset file opening so that file
access is safe if trying to access a bundled file or a file from the disk
*/
package file

import (
	"bytes"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"
)

// the File interface makes accessing bundled files and os.File consistent
type File interface {
	io.Reader
	io.Writer
	io.Seeker
	io.Closer
}

// Read will read a file at the path specified in total and return a byte
// array of the file contents
func Read(path string) ([]byte, error) {
	path = normalizePath(path)
	zipFile, ok := zipFiles[path]
	if !ok {
		return ioutil.ReadFile(path)
	}

	rc, err := zipFile.Open()
	defer rc.Close()
	if err != nil {
		return nil, err
	}
	return ioutil.ReadAll(rc)
}

// ReadString acts like Read but instead return a string. This is useful in certain
// circumstances.
func ReadString(filename string) string {
	s, err := Read(filename)
	if err != nil {
		panic(err)
	}
	return string(s[:])
}

// NewFileData retreives the file info for the path provided. If the file does
// not exist it will return an error
func NewFileData(filename string) (os.FileInfo, error) {
	return stat(filename)
}

// NewFile will return the file if its bundled or on disk and return a File interface
// for the file and an error if it does not exist. The File interface allows for
// consitent access to disk files and zip files.
func NewFile(path string) (File, error) {
	path = normalizePath(path)
	zipFile, ok := zipFiles[path]
	if !ok {
		return os.Open(path)
	}

	rc, err := zipFile.Open()
	if err != nil {
		return nil, err
	}
	all, err := ioutil.ReadAll(rc)
	if err != nil {
		return nil, err
	}
	return &file{
		ReadCloser: rc,
		data:       all,
		reader:     io.NewSectionReader(bytes.NewReader(all), 0, zipFile.FileInfo().Size()),
	}, nil
}

// Create will create and return a new empty file at the pass path
func Create(path string) (File, error) {
	path = normalizePath(path)
	return os.Create(path)
}

// CreateDirectory will create all directories in the path given if they do not exist
func CreateDirectory(path string) error {
	return os.MkdirAll(normalizePath(path), os.ModeDir|os.ModePerm)
}

// Exists will return true if the file exists at the path provided and false if
// the file does not exist.
func Exists(filename string) bool {
	info, err := stat(filename)
	return info != nil && err == nil
}

// Remove will delete a file at the given path and return an error if there was
// and issue
func Remove(path string) error {
	return os.Remove(normalizePath(path))
}

// IsDirectory will return true if the path provided is a directory and false
// if the file does not exist or is not a directory.
func IsDirectory(filename string) bool {
	info, err := stat(filename)
	if err != nil {
		return false
	}
	return info.IsDir()
}

// IsFile will return false if file does not exist or is directory. It will return
// true otherwise.
func IsFile(filename string) bool {
	info, err := stat(filename)
	if err != nil {
		return false
	}
	return !info.IsDir()
}

// IsSymLink will return false if the file does not exist or is not a symlink. It
// will return true if the file is a symlink
func IsSymLink(filename string) bool {
	info, err := stat(filename)
	if err != nil {
		return false
	}
	return (info.Mode() & os.ModeSymlink) != 0
}

// GetSize will return the files size in bytes, it will return 0 if the file does
// not exist
func GetSize(filename string) int32 {
	info, err := stat(filename)
	if err != nil {
		return 0
	}
	return int32(info.Size())
}

// GetLastModified will return the time of when the file was last modified, if
// the file does not exist the time will be 0
func GetLastModified(filename string) time.Time {
	info, err := stat(filename)
	if err != nil {
		return time.Time{}
	}
	return info.ModTime()
}

// Ext will return the extention of the file
func Ext(filename string) string {
	return filepath.Ext(normalizePath(filename))
}
<|endoftext|>


<commit_before>package formula

import (
	"bytes"
	"fmt"
	"strconv"
	"strings"
	"text/scanner"
)

// This VM is quite simple, having only a general purpose
// register (R) and a boolean status register (S).
// Some instructions might contain an integer value (V):
//
//  N - set R = n
//  ADD - set R = R + V
//  SUB - set R = R - V
//  MULT - set R = R * V
//  DIV - set R = R / V
//  MOD - set R = R % V
//  JMPT - jump by V if S is true
//  JMPF - jump by V if S is false
//  EQ - set S = (R == V)
//  NEQ - set S = (R != V)
//  LT - set S = (R < V)
//  LTE - set S = (R <= V)
//  GT - set S = (R > V)
//  GTE - set S = (R >= V)
//  RET - end execution and return V
//
// If the end of the program is reached without finding
// a ret instruction, the last value of S is returned.
// as an integer.

type opCode int

const (
	// Instructions altering R
	opN opCode = iota + 1
	opADD
	opSUB
	opMULT
	opDIV
	opMOD
	// Special instructions
	opRET
	// Jump instructions
	opJMPT
	opJMPF
	// Comparison instructions
	opEQ
	opNEQ
	opLT
	opLTE
	opGT
	opGTE
)

func (o opCode) String() string {
	names := []string{"N", "ADD", "SUB", "MULT", "DIV", "MOD", "RET", "JMPT", "JMPF", "EQ", "NEQ", "LT", "LTE", "GT", "GTE"}
	return names[int(o)-1]
}

func (o opCode) Alters() bool {
	return o <= opMOD
}

func (o opCode) IsSpecial() bool {
	return o == opRET
}

func (o opCode) IsJump() bool {
	return o == opJMPT || o == opJMPF
}

func (o opCode) Compares() bool {
	return o >= opEQ
}

type instruction struct {
	opCode opCode
	value  int
}

func invalid(s *scanner.Scanner, what, val string) ([]*instruction, error) {
	return nil, fmt.Errorf("invalid %s in formula at %s: %q", what, s.Pos(), val)
}

func jumpTarget(s *scanner.Scanner, form string, chr byte) int {
	// look for matching :
	offset := s.Pos().Offset
	paren := 0
	target := -1
	for ii, v := range []byte(form[offset:]) {
		if v == '(' {
			paren++
		} else if v == ')' {
			paren--
			if paren < 0 {
				target = offset + ii
				break
			}
		} else if v == chr && paren == 0 {
			target = offset + ii
			break
		}
	}
	return target
}

func makeJump(s *scanner.Scanner, form string, code *[]*instruction, op opCode, jumps map[int][]*instruction, chr byte) {
	// end of conditional, put the placeholder for a jump
	// and complete it once we reach the matching chr. Store the
	// current position of the jump in its value, so
	// calculating the relative offset is quicker.
	pos := len(*code)
	inst := &instruction{opCode: op, value: pos}
	*code = append(*code, inst)
	target := jumpTarget(s, form, chr)
	jumps[target] = append(jumps[target], inst)
}

func resolveJumps(s *scanner.Scanner, code []*instruction, jumps map[int][]*instruction) {
	// check for incomplete jumps to this location.
	// the pc should point at the next instruction
	// to be added and the jump is relative.
	pc := len(code)
	offset := s.Pos().Offset - 1
	for _, v := range jumps[offset] {
		v.value = pc - v.value - 1
	}
	delete(jumps, offset)
}

func compileVmFormula(form string) (Formula, error) {
	code, err := vmCompile(form)
	if err != nil {
		return nil, err
	}
	code = vmOptimize(code)
	return makeVmFunc(code), nil
}

func vmCompile(form string) ([]*instruction, error) {
	var s scanner.Scanner
	var err error
	s.Init(strings.NewReader(form))
	s.Error = func(s *scanner.Scanner, msg string) {
		err = fmt.Errorf("error parsing plural formula %s: %s", s.Pos(), msg)
	}
	s.Mode = scanner.ScanIdents | scanner.ScanInts
	tok := s.Scan()
	var code []*instruction
	var op bytes.Buffer
	var logic bytes.Buffer
	jumps := make(map[int][]*instruction)
	for tok != scanner.EOF && err == nil {
		switch tok {
		case scanner.Ident:
			if n := s.TokenText(); n != "n" {
				return invalid(&s, "ident", n)
			}
			code = append(code, &instruction{opCode: opN})
		case scanner.Int:
			val, _ := strconv.Atoi(s.TokenText())
			if op.Len() == 0 {
				// return statement
				code = append(code, &instruction{opCode: opRET, value: val})
			} else {
				var opc opCode
				switch op.String() {
				case "+":
					opc = opADD
				case "-":
					opc = opSUB
				case "*":
					opc = opMULT
				case "/":
					opc = opDIV
				case "%":
					opc = opMOD
				case "==":
					opc = opEQ
				case "!=":
					opc = opNEQ
				case "<":
					opc = opLT
				case "<=":
					opc = opLTE
				case ">":
					opc = opGT
				case ">=":
					opc = opGTE
				default:
					return invalid(&s, "op", op.String())
				}
				code = append(code, &instruction{opCode: opc, value: val})
				op.Reset()
			}
		case '?':
			resolveJumps(&s, code, jumps)
			makeJump(&s, form, &code, opJMPF, jumps, ':')
		case ':':
			resolveJumps(&s, code, jumps)
		case '!', '=', '<', '>', '%':
			op.WriteRune(tok)
		case '&', '|':
			// logic operations
			if logic.Len() == 0 {
				logic.WriteRune(tok)
			} else if logic.Len() == 1 {
				b := logic.Bytes()[0]
				if b != byte(tok) {
					return invalid(&s, "token", string(tok))
				}
				if b == '&' {
					makeJump(&s, form, &code, opJMPF, jumps, ':')
				} else {
					makeJump(&s, form, &code, opJMPT, jumps, '?')
				}
				logic.Reset()
			} else {
				return invalid(&s, "token", string(tok))
			}
		case '(':
		case ')':
			resolveJumps(&s, code, jumps)
		default:
			return invalid(&s, "token", string(tok))
		}
		tok = s.Scan()
	}
	return code, nil
}

func removeInstructions(insts []*instruction, start int, count int) []*instruction {
	insts = append(insts[:start], insts[start+count:]...)
	// Check for jumps that might be affected by the removal
	for kk := start; kk >= 0; kk-- {
		if in := insts[kk]; in.opCode.IsJump() && kk+in.value > start {
			in.value -= count
		}
	}
	return insts
}

func vmOptimize(insts []*instruction) []*instruction {
	// The optimizer is quite simple. A first pass looks
	// for multiple comparison instructions that are preceeded
	// by exactly the same instructions and it removes the second
	// group of instructions. A second pass then looks for
	// instructions that set R = N when R is already
	// equal to N and it removes the second instruction.
	cmp := -1
	count := len(insts)
	ii := 0
	for ; ii < count; ii++ {
		v := insts[ii]
		if v.opCode.Compares() {
			if cmp >= 0 {
				delta := ii - cmp
				jj := cmp - 1
				for ; jj >= 0; jj-- {
					i1 := insts[jj]
					if !i1.opCode.Alters() {
						break
					}
					i2 := insts[jj+delta]
					if i1.opCode != i2.opCode || i1.value != i2.value {
						break
					}
				}
				equal := (cmp - 1) - jj
				if equal > 0 {
					ii -= equal
					count -= equal
					insts = removeInstructions(insts, ii, equal)
					continue
				}
			}
			cmp = ii
		}
	}
	n := -1
	for ii = 0; ii < count; ii++ {
		v := insts[ii]
		if v.opCode == opN {
			if n >= 0 {
				insts = removeInstructions(insts, ii, 1)
				ii--
				count--
				continue
			}
			n = ii
		} else if v.opCode.Alters() {
			n = -1
		}
	}
	return insts
}

func makeVmFunc(insts []*instruction) Formula {
	count := len(insts)
	return func(n int) int {
		return vmExec(insts, count, n)
	}
}

func vmExec(insts []*instruction, count int, n int) int {
	var R int
	var S bool
	for ii := 0; ii < count; ii++ {
		i := insts[ii]
		switch i.opCode {
		case opN:
			R = n
		case opADD:
			R += i.value
		case opSUB:
			R -= i.value
		case opMULT:
			R *= i.value
		case opDIV:
			R /= i.value
		case opMOD:
			R %= i.value
		case opRET:
			return i.value
		case opJMPT:
			if S {
				ii += i.value
			}
		case opJMPF:
			if !S {
				ii += i.value
			}
		case opEQ:
			S = R == i.value
		case opNEQ:
			S = R != i.value
		case opLT:
			S = R < i.value
		case opLTE:
			S = R <= i.value
		case opGT:
			S = R > i.value
		case opGTE:
			S = R >= i.value
		}
	}
	return bint(S)
}
<commit_msg>Make opCode a uint8<commit_after>package formula

import (
	"bytes"
	"fmt"
	"strconv"
	"strings"
	"text/scanner"
)

// This VM is quite simple, having only a general purpose
// register (R) and a boolean status register (S).
// Some instructions might contain an integer value (V):
//
//  N - set R = n
//  ADD - set R = R + V
//  SUB - set R = R - V
//  MULT - set R = R * V
//  DIV - set R = R / V
//  MOD - set R = R % V
//  JMPT - jump by V if S is true
//  JMPF - jump by V if S is false
//  EQ - set S = (R == V)
//  NEQ - set S = (R != V)
//  LT - set S = (R < V)
//  LTE - set S = (R <= V)
//  GT - set S = (R > V)
//  GTE - set S = (R >= V)
//  RET - end execution and return V
//
// If the end of the program is reached without finding
// a ret instruction, the last value of S is returned.
// as an integer.

type opCode uint8

const (
	// Instructions altering R
	opN opCode = iota + 1
	opADD
	opSUB
	opMULT
	opDIV
	opMOD
	// Special instructions
	opRET
	// Jump instructions
	opJMPT
	opJMPF
	// Comparison instructions
	opEQ
	opNEQ
	opLT
	opLTE
	opGT
	opGTE
)

func (o opCode) String() string {
	names := []string{"N", "ADD", "SUB", "MULT", "DIV", "MOD", "RET", "JMPT", "JMPF", "EQ", "NEQ", "LT", "LTE", "GT", "GTE"}
	return names[int(o)-1]
}

func (o opCode) Alters() bool {
	return o <= opMOD
}

func (o opCode) IsSpecial() bool {
	return o == opRET
}

func (o opCode) IsJump() bool {
	return o == opJMPT || o == opJMPF
}

func (o opCode) Compares() bool {
	return o >= opEQ
}

type instruction struct {
	opCode opCode
	value  int
}

func invalid(s *scanner.Scanner, what, val string) ([]*instruction, error) {
	return nil, fmt.Errorf("invalid %s in formula at %s: %q", what, s.Pos(), val)
}

func jumpTarget(s *scanner.Scanner, form string, chr byte) int {
	// look for matching :
	offset := s.Pos().Offset
	paren := 0
	target := -1
	for ii, v := range []byte(form[offset:]) {
		if v == '(' {
			paren++
		} else if v == ')' {
			paren--
			if paren < 0 {
				target = offset + ii
				break
			}
		} else if v == chr && paren == 0 {
			target = offset + ii
			break
		}
	}
	return target
}

func makeJump(s *scanner.Scanner, form string, code *[]*instruction, op opCode, jumps map[int][]*instruction, chr byte) {
	// end of conditional, put the placeholder for a jump
	// and complete it once we reach the matching chr. Store the
	// current position of the jump in its value, so
	// calculating the relative offset is quicker.
	pos := len(*code)
	inst := &instruction{opCode: op, value: pos}
	*code = append(*code, inst)
	target := jumpTarget(s, form, chr)
	jumps[target] = append(jumps[target], inst)
}

func resolveJumps(s *scanner.Scanner, code []*instruction, jumps map[int][]*instruction) {
	// check for incomplete jumps to this location.
	// the pc should point at the next instruction
	// to be added and the jump is relative.
	pc := len(code)
	offset := s.Pos().Offset - 1
	for _, v := range jumps[offset] {
		v.value = pc - v.value - 1
	}
	delete(jumps, offset)
}

func compileVmFormula(form string) (Formula, error) {
	code, err := vmCompile(form)
	if err != nil {
		return nil, err
	}
	code = vmOptimize(code)
	return makeVmFunc(code), nil
}

func vmCompile(form string) ([]*instruction, error) {
	var s scanner.Scanner
	var err error
	s.Init(strings.NewReader(form))
	s.Error = func(s *scanner.Scanner, msg string) {
		err = fmt.Errorf("error parsing plural formula %s: %s", s.Pos(), msg)
	}
	s.Mode = scanner.ScanIdents | scanner.ScanInts
	tok := s.Scan()
	var code []*instruction
	var op bytes.Buffer
	var logic bytes.Buffer
	jumps := make(map[int][]*instruction)
	for tok != scanner.EOF && err == nil {
		switch tok {
		case scanner.Ident:
			if n := s.TokenText(); n != "n" {
				return invalid(&s, "ident", n)
			}
			code = append(code, &instruction{opCode: opN})
		case scanner.Int:
			val, _ := strconv.Atoi(s.TokenText())
			if op.Len() == 0 {
				// return statement
				code = append(code, &instruction{opCode: opRET, value: val})
			} else {
				var opc opCode
				switch op.String() {
				case "+":
					opc = opADD
				case "-":
					opc = opSUB
				case "*":
					opc = opMULT
				case "/":
					opc = opDIV
				case "%":
					opc = opMOD
				case "==":
					opc = opEQ
				case "!=":
					opc = opNEQ
				case "<":
					opc = opLT
				case "<=":
					opc = opLTE
				case ">":
					opc = opGT
				case ">=":
					opc = opGTE
				default:
					return invalid(&s, "op", op.String())
				}
				code = append(code, &instruction{opCode: opc, value: val})
				op.Reset()
			}
		case '?':
			resolveJumps(&s, code, jumps)
			makeJump(&s, form, &code, opJMPF, jumps, ':')
		case ':':
			resolveJumps(&s, code, jumps)
		case '!', '=', '<', '>', '%':
			op.WriteRune(tok)
		case '&', '|':
			// logic operations
			if logic.Len() == 0 {
				logic.WriteRune(tok)
			} else if logic.Len() == 1 {
				b := logic.Bytes()[0]
				if b != byte(tok) {
					return invalid(&s, "token", string(tok))
				}
				if b == '&' {
					makeJump(&s, form, &code, opJMPF, jumps, ':')
				} else {
					makeJump(&s, form, &code, opJMPT, jumps, '?')
				}
				logic.Reset()
			} else {
				return invalid(&s, "token", string(tok))
			}
		case '(':
		case ')':
			resolveJumps(&s, code, jumps)
		default:
			return invalid(&s, "token", string(tok))
		}
		tok = s.Scan()
	}
	return code, nil
}

func removeInstructions(insts []*instruction, start int, count int) []*instruction {
	insts = append(insts[:start], insts[start+count:]...)
	// Check for jumps that might be affected by the removal
	for kk := start; kk >= 0; kk-- {
		if in := insts[kk]; in.opCode.IsJump() && kk+in.value > start {
			in.value -= count
		}
	}
	return insts
}

func vmOptimize(insts []*instruction) []*instruction {
	// The optimizer is quite simple. A first pass looks
	// for multiple comparison instructions that are preceeded
	// by exactly the same instructions and it removes the second
	// group of instructions. A second pass then looks for
	// instructions that set R = N when R is already
	// equal to N and it removes the second instruction.
	cmp := -1
	count := len(insts)
	ii := 0
	for ; ii < count; ii++ {
		v := insts[ii]
		if v.opCode.Compares() {
			if cmp >= 0 {
				delta := ii - cmp
				jj := cmp - 1
				for ; jj >= 0; jj-- {
					i1 := insts[jj]
					if !i1.opCode.Alters() {
						break
					}
					i2 := insts[jj+delta]
					if i1.opCode != i2.opCode || i1.value != i2.value {
						break
					}
				}
				equal := (cmp - 1) - jj
				if equal > 0 {
					ii -= equal
					count -= equal
					insts = removeInstructions(insts, ii, equal)
					continue
				}
			}
			cmp = ii
		}
	}
	n := -1
	for ii = 0; ii < count; ii++ {
		v := insts[ii]
		if v.opCode == opN {
			if n >= 0 {
				insts = removeInstructions(insts, ii, 1)
				ii--
				count--
				continue
			}
			n = ii
		} else if v.opCode.Alters() {
			n = -1
		}
	}
	return insts
}

func makeVmFunc(insts []*instruction) Formula {
	count := len(insts)
	return func(n int) int {
		return vmExec(insts, count, n)
	}
}

func vmExec(insts []*instruction, count int, n int) int {
	var R int
	var S bool
	for ii := 0; ii < count; ii++ {
		i := insts[ii]
		switch i.opCode {
		case opN:
			R = n
		case opADD:
			R += i.value
		case opSUB:
			R -= i.value
		case opMULT:
			R *= i.value
		case opDIV:
			R /= i.value
		case opMOD:
			R %= i.value
		case opRET:
			return i.value
		case opJMPT:
			if S {
				ii += i.value
			}
		case opJMPF:
			if !S {
				ii += i.value
			}
		case opEQ:
			S = R == i.value
		case opNEQ:
			S = R != i.value
		case opLT:
			S = R < i.value
		case opLTE:
			S = R <= i.value
		case opGT:
			S = R > i.value
		case opGTE:
			S = R >= i.value
		}
	}
	return bint(S)
}
<|endoftext|>


<commit_before>package copy_application_source

import (
	"fmt"
	"strings"

	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	"github.com/cloudfoundry/cli/cf/net"
)

type CopyApplicationSourceRepository interface {
	CopyApplication(sourceAppGuid, targetAppGuid string) error
}

type CloudControllerApplicationSourceRepository struct {
	config  core_config.Reader
	gateway net.Gateway
}

func NewCloudControllerCopyApplicationSourceRepository(config core_config.Reader, gateway net.Gateway) *CloudControllerApplicationSourceRepository {
	return &CloudControllerApplicationSourceRepository{
		config:  config,
		gateway: gateway,
	}
}

func (repo *CloudControllerApplicationSourceRepository) CopyApplication(sourceAppGuid, targetAppGuid string) error {
	url := fmt.Sprintf("%s/v2/apps/%s/copy_bits", repo.config.ApiEndpoint(), targetAppGuid)
	body := fmt.Sprintf(`{"source_app_guid":"%s"}`, sourceAppGuid)
	return repo.gateway.CreateResource(url, strings.NewReader(body))
}
<commit_msg>copy_application_source now polls on copy-bits endpoint<commit_after>package copy_application_source

import (
	"fmt"
	"strings"

	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	"github.com/cloudfoundry/cli/cf/net"
)

type CopyApplicationSourceRepository interface {
	CopyApplication(sourceAppGuid, targetAppGuid string) error
}

type CloudControllerApplicationSourceRepository struct {
	config  core_config.Reader
	gateway net.Gateway
}

func NewCloudControllerCopyApplicationSourceRepository(config core_config.Reader, gateway net.Gateway) *CloudControllerApplicationSourceRepository {
	return &CloudControllerApplicationSourceRepository{
		config:  config,
		gateway: gateway,
	}
}

func (repo *CloudControllerApplicationSourceRepository) CopyApplication(sourceAppGuid, targetAppGuid string) error {
	url := fmt.Sprintf("%s/v2/apps/%s/copy_bits", repo.config.ApiEndpoint(), targetAppGuid)
	body := fmt.Sprintf(`{"source_app_guid":"%s"}`, sourceAppGuid)
	return repo.gateway.CreateResource(url, strings.NewReader(body), new(interface{}))
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.130"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.97", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<commit_msg>fnlb: 0.0.131 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.131"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.98", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.146"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.113", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<commit_msg>fnlb: 0.0.147 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.147"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.114", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<|endoftext|>


<commit_before>package orm

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/rbastic/dyndao/object"
	"github.com/rbastic/dyndao/schema"
	"strings"
)

var (
	crossJoinAllSQL = "SELECT %s FROM %s p, %s c WHERE p.%s = c.%s"
)

func (o *ORM) crossJoinAllHelper(ctx context.Context, tx *sql.Tx, parentTbl, childTbl, linkField, sqlStr string, allAliases []string, parentSchTbl, childSchTbl *schema.Table) (*object.Array, error) {
	sg := o.GetSQLBuilder()

	// Determines whether we are running inside a transaction or not,
	// returning stmt either way
	stmt, err := stmtFromDbOrTx(ctx, o, tx, sqlStr)
	if err != nil {
		return nil, err
	}

	defer func() {
		stmtErr := stmt.Close()
		if stmtErr != nil {
			o.Debug("%s", err)
			err = stmtErr
		}
	}()

	var res *sql.Rows
	res, err = stmt.Query()
	if err != nil {
		return nil, err
	}

	defer func() {
		resErr := res.Close()
		if resErr != nil {
			sg.Debug("%s", err)
			err = resErr
		}
	}()

	columnTypes, err := res.ColumnTypes()
	if err != nil {
		return nil, err
	}

	columnPointers, err := sg.MakeColumnPointers(sg, parentSchTbl, allAliases, columnTypes)
	if err != nil {
		return nil, err
	}

	var objectArray object.Array
	for res.Next() {
		if err := res.Scan(columnPointers...); err != nil {
			if sg.Tracing {
				o.Debug("CrossJoinAll/res.Scan err= "+err.Error()+" columnPointers=%s\n", columnPointers...)
			}

			return nil, err
		}

		// Bind the main response object object
		obj := object.New("INTERIM")
		err = sg.BindObject(sg, parentSchTbl, allAliases, columnPointers, columnTypes, obj)
		if err != nil {
			return nil, err
		}

		obj.MarkDirty(false)
		obj.ResetChangedColumns()

		topObj, err := o.mapFromInterim(ctx, tx, obj, parentSchTbl, childSchTbl)
		if err != nil {

			return nil, err
		}
		objectArray = append(objectArray, topObj)
	}

	err = res.Err()
	if err != nil {
		return nil, err
	}

	return &objectArray, nil
}

func (o *ORM) CrossJoinAll(ctx context.Context, tx *sql.Tx, parentTbl, childTbl, linkField string) (*object.Array, error) {
	sch := o.GetSchema()
	parentSchTbl := sch.GetTable(parentTbl)
	childSchTbl := sch.GetTable(childTbl)

	allCols, allAliases := o.JoinEssentialColumns(sch, parentSchTbl, childSchTbl, parentTbl, "p", childTbl, "c")
	allColsStr := strings.Join(allCols, ",")

	fmtSql := fmt.Sprintf(crossJoinSQL, allColsStr, parentTbl, childTbl, linkField, linkField)

	o.Debug("CrossJoinAll SQL='%s' allAliases=%v", fmtSql, allAliases)

	return o.crossJoinAllHelper(ctx, tx, parentTbl, childTbl, linkField, fmtSql, allAliases, parentSchTbl, childSchTbl)
}

<commit_msg>oops.<commit_after>package orm

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/rbastic/dyndao/object"
	"github.com/rbastic/dyndao/schema"
	"strings"
)

var (
	crossJoinAllSQL = "SELECT %s FROM %s p, %s c WHERE p.%s = c.%s"
)

func (o *ORM) crossJoinAllHelper(ctx context.Context, tx *sql.Tx, parentTbl, childTbl, linkField, sqlStr string, allAliases []string, parentSchTbl, childSchTbl *schema.Table) (*object.Array, error) {
	sg := o.GetSQLBuilder()

	// Determines whether we are running inside a transaction or not,
	// returning stmt either way
	stmt, err := stmtFromDbOrTx(ctx, o, tx, sqlStr)
	if err != nil {
		return nil, err
	}

	defer func() {
		stmtErr := stmt.Close()
		if stmtErr != nil {
			o.Debug("%s", err)
			err = stmtErr
		}
	}()

	var res *sql.Rows
	res, err = stmt.Query()
	if err != nil {
		return nil, err
	}

	defer func() {
		resErr := res.Close()
		if resErr != nil {
			sg.Debug("%s", err)
			err = resErr
		}
	}()

	columnTypes, err := res.ColumnTypes()
	if err != nil {
		return nil, err
	}

	columnPointers, err := sg.MakeColumnPointers(sg, parentSchTbl, allAliases, columnTypes)
	if err != nil {
		return nil, err
	}

	var objectArray object.Array
	for res.Next() {
		if err := res.Scan(columnPointers...); err != nil {
			if sg.Tracing {
				o.Debug("CrossJoinAll/res.Scan err= "+err.Error()+" columnPointers=%s\n", columnPointers...)
			}

			return nil, err
		}

		// Bind the main response object object
		obj := object.New("INTERIM")
		err = sg.BindObject(sg, parentSchTbl, allAliases, columnPointers, columnTypes, obj)
		if err != nil {
			return nil, err
		}

		obj.MarkDirty(false)
		obj.ResetChangedColumns()

		topObj, err := o.mapFromInterim(ctx, tx, obj, parentSchTbl, childSchTbl)
		if err != nil {

			return nil, err
		}
		objectArray = append(objectArray, topObj)
	}

	err = res.Err()
	if err != nil {
		return nil, err
	}

	return &objectArray, nil
}

func (o *ORM) CrossJoinAll(ctx context.Context, tx *sql.Tx, parentTbl, childTbl, linkField string) (*object.Array, error) {
	sch := o.GetSchema()
	parentSchTbl := sch.GetTable(parentTbl)
	childSchTbl := sch.GetTable(childTbl)

	allCols, allAliases := o.JoinEssentialColumns(sch, parentSchTbl, childSchTbl, parentTbl, "p", childTbl, "c")
	allColsStr := strings.Join(allCols, ",")

	fmtSql := fmt.Sprintf(crossJoinAllSQL, allColsStr, parentTbl, childTbl, linkField, linkField)

	o.Debug("CrossJoinAll SQL='%s' allAliases=%v", fmtSql, allAliases)

	return o.crossJoinAllHelper(ctx, tx, parentTbl, childTbl, linkField, fmtSql, allAliases, parentSchTbl, childSchTbl)
}

<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.253"

func main() {
	// XXX (reed): normalize
	level, err := logrus.ParseLevel(os.Getenv("LOG_LEVEL"))
	if err != nil {
		level = logrus.InfoLevel
	}
	logrus.SetLevel(level)

	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.220", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory; use k8s for kuberneted")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.StringVar(&conf.MgmtListen, "mgmt-listen", ":8081", "management port to run on")
	flag.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", 0, "graceful shutdown timeout")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckHealthy, "hc-healthy", 1, "threshold of success checks to declare node healthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.StringVar(&conf.Namespace, "namespace", "", "kubernetes namespace to monitor")
	flag.StringVar(&conf.LabelSelector, "label-selector", "", "kubernetes label selector to monitor")
	flag.IntVar(&conf.TargetPort, "target-port", 8080, "kubernetes port to target on selected pods")

	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	db, err := lb.NewDB(conf) // Handles case where DBurl == "k8s"
	if err != nil {
		logrus.WithError(err).Fatal("error setting up database")
	}
	defer db.Close()

	g, err := lb.NewAllGrouper(conf, db)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	servers := make([]*http.Server, 0, 1)
	handler := lb.NewProxy(k, g, r, conf)

	// a separate mgmt listener is requested? then let's create a LB traffic only server
	if conf.Listen != conf.MgmtListen {
		servers = append(servers, &http.Server{Addr: conf.Listen, Handler: handler})
		handler = lb.NullHandler()
	}

	// add mgmt endpoints to the handler
	handler = g.Wrap(handler) // add/del/list endpoints
	handler = r.Wrap(handler) // stats / dash endpoint

	servers = append(servers, &http.Server{Addr: conf.MgmtListen, Handler: handler})
	serve(servers, &conf)
}

func serve(servers []*http.Server, conf *lb.Config) {

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)

	for i := 0; i < len(servers); i++ {
		go func(idx int) {
			err := servers[idx].ListenAndServe()
			if err != nil && err != http.ErrServerClosed {
				logrus.WithFields(logrus.Fields{"server_id": idx}).WithError(err).Fatal("server error")
			} else {
				logrus.WithFields(logrus.Fields{"server_id": idx}).Info("server stopped")
			}
		}(i)
	}

	sig := <-ch
	logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")

	for i := 0; i < len(servers); i++ {

		ctx := context.Background()

		if conf.ShutdownTimeout > 0 {
			tmpCtx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.ShutdownTimeout)*time.Second)
			ctx = tmpCtx
			defer cancel()
		}

		err := servers[i].Shutdown(ctx) // safe shutdown
		if err != nil {
			logrus.WithFields(logrus.Fields{"server_id": i}).WithError(err).Fatal("server shutdown error")
		} else {
			logrus.WithFields(logrus.Fields{"server_id": i}).Info("server shutdown")
		}
	}
}
<commit_msg>fnlb: 0.0.254 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.254"

func main() {
	// XXX (reed): normalize
	level, err := logrus.ParseLevel(os.Getenv("LOG_LEVEL"))
	if err != nil {
		level = logrus.InfoLevel
	}
	logrus.SetLevel(level)

	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.221", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory; use k8s for kuberneted")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.StringVar(&conf.MgmtListen, "mgmt-listen", ":8081", "management port to run on")
	flag.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", 0, "graceful shutdown timeout")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckHealthy, "hc-healthy", 1, "threshold of success checks to declare node healthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.StringVar(&conf.Namespace, "namespace", "", "kubernetes namespace to monitor")
	flag.StringVar(&conf.LabelSelector, "label-selector", "", "kubernetes label selector to monitor")
	flag.IntVar(&conf.TargetPort, "target-port", 8080, "kubernetes port to target on selected pods")

	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	db, err := lb.NewDB(conf) // Handles case where DBurl == "k8s"
	if err != nil {
		logrus.WithError(err).Fatal("error setting up database")
	}
	defer db.Close()

	g, err := lb.NewAllGrouper(conf, db)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	servers := make([]*http.Server, 0, 1)
	handler := lb.NewProxy(k, g, r, conf)

	// a separate mgmt listener is requested? then let's create a LB traffic only server
	if conf.Listen != conf.MgmtListen {
		servers = append(servers, &http.Server{Addr: conf.Listen, Handler: handler})
		handler = lb.NullHandler()
	}

	// add mgmt endpoints to the handler
	handler = g.Wrap(handler) // add/del/list endpoints
	handler = r.Wrap(handler) // stats / dash endpoint

	servers = append(servers, &http.Server{Addr: conf.MgmtListen, Handler: handler})
	serve(servers, &conf)
}

func serve(servers []*http.Server, conf *lb.Config) {

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)

	for i := 0; i < len(servers); i++ {
		go func(idx int) {
			err := servers[idx].ListenAndServe()
			if err != nil && err != http.ErrServerClosed {
				logrus.WithFields(logrus.Fields{"server_id": idx}).WithError(err).Fatal("server error")
			} else {
				logrus.WithFields(logrus.Fields{"server_id": idx}).Info("server stopped")
			}
		}(i)
	}

	sig := <-ch
	logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")

	for i := 0; i < len(servers); i++ {

		ctx := context.Background()

		if conf.ShutdownTimeout > 0 {
			tmpCtx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.ShutdownTimeout)*time.Second)
			ctx = tmpCtx
			defer cancel()
		}

		err := servers[i].Shutdown(ctx) // safe shutdown
		if err != nil {
			logrus.WithFields(logrus.Fields{"server_id": i}).WithError(err).Fatal("server shutdown error")
		} else {
			logrus.WithFields(logrus.Fields{"server_id": i}).Info("server shutdown")
		}
	}
}
<|endoftext|>


<commit_before>package easyreq

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"strings"
	"testing"
)

func testReq(t *testing.T, w http.ResponseWriter, r *http.Request) {
	ctype := r.Header.Get("Content-Type")
	m := make(url.Values)

	if r.Method != "GET" && ctype == "" {
		t.Log(ctype)
		t.Fail()
	}

	if strings.Contains(ctype, "json") {
		decoder := json.NewDecoder(r.Body)
		if err := decoder.Decode(&m); err != nil {
			t.Fatal(err)
		}

	} else if strings.Contains(ctype, "form") {
		if err := r.ParseMultipartForm(10 << 20); err != nil {
			t.Fatal(err)
		}
		m = r.Form
	} else {
		m = r.URL.Query()
	}

	if r.URL.Query().Get("test") != "true" {
		t.Fatal(r.URL.String())
	}

	if len(m["Name"]) == 0 || m["Name"][0] != "John" {
		t.Log(r.URL.String())
		t.Fatal(m)
	}

	if strings.Contains(ctype, "multipart") {
		if _, _, err := r.FormFile("File"); err != nil {
			t.Fatal(err)
		}
	}
}

func TestPostForm(t *testing.T) {
	testForm("POST", t)
}

func TestPutForm(t *testing.T) {
	testForm("PUT", t)
}

func TestMultipartForm(t *testing.T) {
	handler := func(w http.ResponseWriter, r *http.Request) { testReq(t, w, r) }
	ts := httptest.NewServer(http.HandlerFunc(handler))
	defer ts.Close()

	f := Form{}
	f.Field().Add("Name", "John")
	f.File().Add("File", "test-files/logo.png")

	req, err := f.Request("POST", ts.URL+"/?test=true")
	if err != nil {
		t.Fatal(err)
	}

	if _, err := http.DefaultClient.Do(req); err != nil {
		t.Fatal(err)
	}

	contentType := req.Header.Get("Content-Type")
	if contentType == "application/x-www-form-urlencoded" {
		t.Fail()
	}

	if _, err := f.Do("POST", ts.URL+"/?test=true"); err != nil {
		t.Fatal(err)
	}
}

func TestFailedCase(t *testing.T) {
	f := Form{}
	f.Field().Add("Name", "John")
	f.File().Add("File", "test-files/logo1.png") //file doesn't exists

	_, err := f.Request("POST", "http://local/")
	if !os.IsNotExist(err) {
		t.Fatal(err)
	}
}

func TestGetForm(t *testing.T) {
	testForm("GET", t)
}

func testForm(verb string, t *testing.T) {
	handler := func(w http.ResponseWriter, r *http.Request) { testReq(t, w, r) }
	ts := httptest.NewServer(http.HandlerFunc(handler))
	defer ts.Close()

	f := NewForm(nil, nil)
	f.Field().Add("Name", "John")
	f.Field().Add("Likes", "Ice Cream")
	f.Header().Add("Host", "example.com")

	req, err := f.Request(verb, ts.URL+"/?test=true")
	if err != nil {
		t.Fatal(err)
	}

	if req.Method != verb {
		t.Log(req.Method)
		t.Fail()
	}

	if req.Header.Get("Host") != "example.com" {
		t.Fail()
	}

	if _, err := http.DefaultClient.Do(req); err != nil {
		t.Fatal(err)
	}
}
<commit_msg>Reorganize test code<commit_after>package easyreq

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"strings"
	"testing"
)

func TestMultipartForm(t *testing.T) {
	handler := func(w http.ResponseWriter, r *http.Request) { testReq(t, w, r) }
	ts := httptest.NewServer(http.HandlerFunc(handler))
	defer ts.Close()

	f := Form{}
	f.Field().Add("Name", "John")
	f.File().Add("File", "test-files/logo.png")

	req, err := f.Request("POST", ts.URL+"/?test=true")
	if err != nil {
		t.Fatal(err)
	}

	if _, err := http.DefaultClient.Do(req); err != nil {
		t.Fatal(err)
	}

	contentType := req.Header.Get("Content-Type")
	if contentType == "application/x-www-form-urlencoded" {
		t.Fail()
	}

	if _, err := f.Do("POST", ts.URL+"/?test=true"); err != nil {
		t.Fatal(err)
	}
}

func TestPostForm(t *testing.T) {
	testForm("POST", t)
}

func TestPutForm(t *testing.T) {
	testForm("PUT", t)
}

func TestGetForm(t *testing.T) {
	testForm("GET", t)
}

func testForm(verb string, t *testing.T) {
	handler := func(w http.ResponseWriter, r *http.Request) { testReq(t, w, r) }
	ts := httptest.NewServer(http.HandlerFunc(handler))
	defer ts.Close()

	f := NewForm(nil, nil)
	f.Field().Add("Name", "John")
	f.Field().Add("Likes", "Ice Cream")
	f.Header().Add("Host", "example.com")

	req, err := f.Request(verb, ts.URL+"/?test=true")
	if err != nil {
		t.Fatal(err)
	}

	if req.Method != verb {
		t.Log(req.Method)
		t.Fail()
	}

	if req.Header.Get("Host") != "example.com" {
		t.Fail()
	}

	if _, err := http.DefaultClient.Do(req); err != nil {
		t.Fatal(err)
	}
}

func testReq(t *testing.T, w http.ResponseWriter, r *http.Request) {
	ctype := r.Header.Get("Content-Type")
	m := make(url.Values)

	if r.Method != "GET" && ctype == "" {
		t.Log(ctype)
		t.Fail()
	}

	if strings.Contains(ctype, "json") {
		decoder := json.NewDecoder(r.Body)
		if err := decoder.Decode(&m); err != nil {
			t.Fatal(err)
		}

	} else if strings.Contains(ctype, "form") {
		if err := r.ParseMultipartForm(10 << 20); err != nil {
			t.Fatal(err)
		}
		m = r.Form
	} else {
		m = r.URL.Query()
	}

	if r.URL.Query().Get("test") != "true" {
		t.Fatal(r.URL.String())
	}

	if len(m["Name"]) == 0 || m["Name"][0] != "John" {
		t.Log(r.URL.String())
		t.Fatal(m)
	}

	if strings.Contains(ctype, "multipart") {
		if _, _, err := r.FormFile("File"); err != nil {
			t.Fatal(err)
		}
	}
}

func TestFailedCase(t *testing.T) {
	f := Form{}
	f.Field().Add("Name", "John")
	f.File().Add("File", "test-files/logo1.png") //file doesn't exists

	_, err := f.Request("POST", "http://local/")
	if !os.IsNotExist(err) {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package lfs

import (
	"bytes"
	"fmt"
	"net/url"
	"os/exec"
	"strings"
)

type credentialFetcher interface {
	Credentials() Creds
}

type credentialFunc func(Creds, string) (credentialFetcher, error)

var execCreds credentialFunc

func credentials(u *url.URL) (Creds, error) {
	creds := Creds{"protocol": u.Scheme, "host": u.Host}
	cmd, err := execCreds(creds, "fill")
	if err != nil {
		return nil, err
	}
	return cmd.Credentials(), nil
}

type CredentialCmd struct {
	output     *bytes.Buffer
	SubCommand string
	*exec.Cmd
}

func NewCommand(input Creds, subCommand string) *CredentialCmd {
	buf1 := new(bytes.Buffer)
	cmd := exec.Command("git", "credential", subCommand)

	cmd.Stdin = input.Buffer()
	cmd.Stdout = buf1
	/*
		There is a reason we don't hook up stderr here:
		Git's credential cache daemon helper does not close its stderr, so if this
		process is the process that fires up the daemon, it will wait forever
		(until the daemon exits, really) trying to read from stderr.

		See https://github.com/github/git-lfs/issues/117 for more details.
	*/

	return &CredentialCmd{buf1, subCommand, cmd}
}

func (c *CredentialCmd) StdoutString() string {
	return c.output.String()
}

func (c *CredentialCmd) Credentials() Creds {
	creds := make(Creds)

	for _, line := range strings.Split(c.StdoutString(), "\n") {
		pieces := strings.SplitN(line, "=", 2)
		if len(pieces) < 2 {
			continue
		}
		creds[pieces[0]] = pieces[1]
	}

	return creds
}

type Creds map[string]string

func (c Creds) Buffer() *bytes.Buffer {
	buf := new(bytes.Buffer)

	for k, v := range c {
		buf.Write([]byte(k))
		buf.Write([]byte("="))
		buf.Write([]byte(v))
		buf.Write([]byte("\n"))
	}

	return buf
}

func init() {
	execCreds = func(input Creds, subCommand string) (credentialFetcher, error) {
		cmd := NewCommand(input, subCommand)
		err := cmd.Start()
		if err == nil {
			err = cmd.Wait()
		}

		if err != nil {
			return cmd, fmt.Errorf("'git credential %s' error: %s\n", cmd.SubCommand, err.Error())
		}

		return cmd, nil
	}
}
<commit_msg>アアー アアアア アー<commit_after>package lfs

import (
	"bytes"
	"fmt"
	"net/url"
	"os"
	"os/exec"
	"strings"
)

type credentialFetcher interface {
	Credentials() Creds
}

type credentialFunc func(Creds, string) (credentialFetcher, error)

var execCreds credentialFunc

func credentials(u *url.URL) (Creds, error) {
	creds := Creds{"protocol": u.Scheme, "host": u.Host}
	cmd, err := execCreds(creds, "fill")
	if err != nil {
		return nil, err
	}
	return cmd.Credentials(), nil
}

type CredentialCmd struct {
	output     *bytes.Buffer
	SubCommand string
	*exec.Cmd
}

func NewCommand(input Creds, subCommand string) *CredentialCmd {
	buf1 := new(bytes.Buffer)
	cmd := exec.Command("git", "credential", subCommand)

	cmd.Stdin = input.Buffer()
	cmd.Stdout = buf1
	/*
		There is a reason we don't hook up stderr here:
		Git's credential cache daemon helper does not close its stderr, so if this
		process is the process that fires up the daemon, it will wait forever
		(until the daemon exits, really) trying to read from stderr.

		See https://github.com/github/git-lfs/issues/117 for more details.
	*/

	return &CredentialCmd{buf1, subCommand, cmd}
}

func (c *CredentialCmd) StdoutString() string {
	return c.output.String()
}

func (c *CredentialCmd) Credentials() Creds {
	creds := make(Creds)

	for _, line := range strings.Split(c.StdoutString(), "\n") {
		pieces := strings.SplitN(line, "=", 2)
		if len(pieces) < 2 {
			continue
		}
		creds[pieces[0]] = pieces[1]
	}

	return creds
}

type Creds map[string]string

func (c Creds) Buffer() *bytes.Buffer {
	buf := new(bytes.Buffer)

	for k, v := range c {
		buf.Write([]byte(k))
		buf.Write([]byte("="))
		buf.Write([]byte(v))
		buf.Write([]byte("\n"))
	}

	return buf
}

func init() {
	execCreds = func(input Creds, subCommand string) (credentialFetcher, error) {
		cmd := NewCommand(input, subCommand)
		err := cmd.Start()
		if err == nil {
			err = cmd.Wait()
		}

		if exitErr, ok := err.(*exec.ExitError); ok {
			if exitErr.ProcessState.Success() == false && os.Getenv("GIT_TERMINAL_PROMPT") == "0" {
				return nil, fmt.Errorf("Change the GIT_TERMINAL_PROMPT env var to be prompted to enter your credentials for %s://%s.",
					input["protocol"], input["host"])
			}
		}

		if err != nil {
			return cmd, fmt.Errorf("'git credential %s' error: %s\n", cmd.SubCommand, err.Error())
		}

		return cmd, nil
	}
}
<|endoftext|>