<commit_before>package metrics

import (
	log "github.com/Sirupsen/logrus"
	"github.com/smancke/guble/gubled/config"

	"expvar"
	"fmt"
	"io"
	"net/http"
	"os"
)

// Enabled is a global flag for enabling/disabling the collection of metrics.
// Metrics are enabled if a specific environment variable is defined with any value.
var Enabled = len(os.Getenv("GUBLE_METRICS")) > 0

// IntVar is an interface for the operations defined on expvar.Int
type IntVar interface {
	Add(int64)
	Set(int64)
}

type emptyInt struct{}

// Dummy functions on EmptyInt
func (v *emptyInt) Add(delta int64) {}

func (v *emptyInt) Set(value int64) {}

// NewInt returns an expvar.Int or a dummy emptyInt, depending on the Enabled flag
func NewInt(name string) IntVar {
	if *config.Metrics.Enabled {
		return expvar.NewInt(name)
	}
	return &emptyInt{}
}

// HttpHandler is a HTTP handler writing the current metrics to the http.ResponseWriter
func HttpHandler(rw http.ResponseWriter, r *http.Request) {
	rw.Header().Set("Content-Type", "application/json; charset=utf-8")
	writeMetrics(rw)
}

func writeMetrics(w io.Writer) {
	fmt.Fprintf(w, "{\n")
	first := true
	expvar.Do(func(kv expvar.KeyValue) {
		if !first {
			fmt.Fprintf(w, ",\n")
		}
		first = false
		fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value)
	})
	fmt.Fprintf(w, "\n}\n")
}

// LogOnDebugLevel logs all the current metrics, if logging is on Debug level.
func LogOnDebugLevel() {
	if !*config.Metrics.Enabled {
		log.Debug("metrics: not enabled")
		return
	}
	if log.GetLevel() == log.DebugLevel {
		fields := log.Fields{}
		expvar.Do(func(kv expvar.KeyValue) {
			fields[kv.Key] = kv.Value
		})
		log.WithFields(fields).Debug("metrics: current values")
	}
}
<commit_msg>removing unused global flag for metrics<commit_after>package metrics

import (
	"github.com/smancke/guble/gubled/config"

	log "github.com/Sirupsen/logrus"

	"expvar"
	"fmt"
	"io"
	"net/http"
)

// IntVar is an interface for the operations defined on expvar.Int
type IntVar interface {
	Add(int64)
	Set(int64)
}

type emptyInt struct{}

// Dummy functions on EmptyInt
func (v *emptyInt) Add(delta int64) {}

func (v *emptyInt) Set(value int64) {}

// NewInt returns an expvar.Int or a dummy emptyInt, depending on the Enabled flag
func NewInt(name string) IntVar {
	if *config.Metrics.Enabled {
		return expvar.NewInt(name)
	}
	return &emptyInt{}
}

// HttpHandler is a HTTP handler writing the current metrics to the http.ResponseWriter
func HttpHandler(rw http.ResponseWriter, r *http.Request) {
	rw.Header().Set("Content-Type", "application/json; charset=utf-8")
	writeMetrics(rw)
}

func writeMetrics(w io.Writer) {
	fmt.Fprintf(w, "{\n")
	first := true
	expvar.Do(func(kv expvar.KeyValue) {
		if !first {
			fmt.Fprintf(w, ",\n")
		}
		first = false
		fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value)
	})
	fmt.Fprintf(w, "\n}\n")
}

// LogOnDebugLevel logs all the current metrics, if logging is on Debug level.
func LogOnDebugLevel() {
	if !*config.Metrics.Enabled {
		log.Debug("metrics: not enabled")
		return
	}
	if log.GetLevel() == log.DebugLevel {
		fields := log.Fields{}
		expvar.Do(func(kv expvar.KeyValue) {
			fields[kv.Key] = kv.Value
		})
		log.WithFields(fields).Debug("metrics: current values")
	}
}
<|endoftext|>


<commit_before>// Copyright 2018 Jigsaw Operations LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package metrics

import (
	"io"
	"time"

	onet "github.com/Jigsaw-Code/outline-ss-server/net"
	"github.com/prometheus/client_golang/prometheus"
)

// ShadowsocksMetrics registers metrics for the Shadowsocks service.
type ShadowsocksMetrics interface {
	SetNumAccessKeys(numKeys int, numPorts int)
	AddClientUDPPacket(accessKey, status string, clientProxyBytes, proxyTargetBytes int)
	AddTargetUDPPacket(accessKey, status string, targetProxyBytes, proxyClientBytes int)
	AddOpenTCPConnection()
	AddClosedTCPConnection(accessKey, status string, data ProxyMetrics, duration time.Duration)
}

type shadowsocksMetrics struct {
	accessKeys           prometheus.Gauge
	ports                prometheus.Gauge
	tcpOpenConnections   prometheus.Counter
	tcpClosedConnections *prometheus.CounterVec
	// TODO: Define a time window for the duration summary (e.g. 1 hour)
	tcpConnectionDurationMs *prometheus.SummaryVec

	// TODO: Add per network/location metrics.
	// TODO: Add time to first byte.
	dataClientProxyBytes *prometheus.CounterVec
	dataProxyTargetBytes *prometheus.CounterVec
	dataTargetProxyBytes *prometheus.CounterVec
	dataProxyClientBytes *prometheus.CounterVec
}

func NewShadowsocksMetrics() ShadowsocksMetrics {
	m := &shadowsocksMetrics{
		accessKeys: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: "shadowsocks",
			Name:      "keys",
			Help:      "Count of access keys",
		}),
		ports: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: "shadowsocks",
			Name:      "ports",
			Help:      "Count of open Shadowsocks ports",
		}),
		tcpOpenConnections: prometheus.NewCounter(prometheus.CounterOpts{
			Namespace: "shadowsocks",
			Subsystem: "tcp",
			Name:      "open_connections",
			Help:      "Count of open TCP connections",
		}),
		tcpClosedConnections: prometheus.NewCounterVec(prometheus.CounterOpts{
			Namespace: "shadowsocks",
			Subsystem: "tcp",
			Name:      "closed_connections",
			Help:      "Count of closed TCP connections",
		}, []string{"access_key", "status"}),
		tcpConnectionDurationMs: prometheus.NewSummaryVec(
			prometheus.SummaryOpts{
				Namespace:  "shadowsocks",
				Subsystem:  "tcp",
				Name:       "connection_duration_ms",
				Help:       "TCP connection duration distributions.",
				Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
			}, []string{"access_key", "status"}),
		dataClientProxyBytes: prometheus.NewCounterVec(
			prometheus.CounterOpts{
				Namespace: "shadowsocks",
				Name:      "data_client_proxy_bytes",
				Help:      "Bytes tranferred from client to proxy.",
			}, []string{"proto", "access_key", "status"}),
		dataProxyTargetBytes: prometheus.NewCounterVec(
			prometheus.CounterOpts{
				Namespace: "shadowsocks",
				Name:      "data_proxy_target_bytes",
				Help:      "Bytes tranferred from proxy to target.",
			}, []string{"proto", "access_key", "status"}),
		dataTargetProxyBytes: prometheus.NewCounterVec(
			prometheus.CounterOpts{
				Namespace: "shadowsocks",
				Name:      "data_target_proxy_bytes",
				Help:      "Bytes tranferred from target to proxy.",
			}, []string{"proto", "access_key", "status"}),
		dataProxyClientBytes: prometheus.NewCounterVec(
			prometheus.CounterOpts{
				Namespace: "shadowsocks",
				Name:      "data_proxy_client_bytes",
				Help:      "Bytes tranferred from proxy to client.",
			}, []string{"proto", "access_key", "status"}),
	}
	// TODO: Is it possible to pass where to register the collectors?
	prometheus.MustRegister(m.accessKeys, m.ports, m.tcpOpenConnections, m.tcpClosedConnections, m.tcpConnectionDurationMs,
		m.dataClientProxyBytes, m.dataProxyTargetBytes, m.dataTargetProxyBytes, m.dataProxyClientBytes)
	return m
}

func (m *shadowsocksMetrics) SetNumAccessKeys(numKeys int, ports int) {
	m.accessKeys.Set(float64(numKeys))
	m.ports.Set(float64(ports))
}

func (m *shadowsocksMetrics) AddOpenTCPConnection() {
	m.tcpOpenConnections.Inc()
}

func (m *shadowsocksMetrics) AddClosedTCPConnection(accessKey, status string, data ProxyMetrics, duration time.Duration) {
	m.tcpClosedConnections.WithLabelValues(accessKey, status).Inc()
	m.tcpConnectionDurationMs.WithLabelValues(accessKey, status).Observe(duration.Seconds() * 1000)
	m.dataClientProxyBytes.WithLabelValues("tcp", accessKey, status).Add(float64(data.ClientProxy))
	m.dataProxyTargetBytes.WithLabelValues("tcp", accessKey, status).Add(float64(data.ProxyTarget))
	m.dataTargetProxyBytes.WithLabelValues("tcp", accessKey, status).Add(float64(data.TargetProxy))
	m.dataProxyClientBytes.WithLabelValues("tcp", accessKey, status).Add(float64(data.ProxyClient))
}

func (m *shadowsocksMetrics) AddClientUDPPacket(accessKey, status string, clientProxyBytes, proxyTargetBytes int) {
	m.dataClientProxyBytes.WithLabelValues("udp", accessKey, status).Add(float64(clientProxyBytes))
	m.dataProxyTargetBytes.WithLabelValues("udp", accessKey, status).Add(float64(proxyTargetBytes))
}

func (m *shadowsocksMetrics) AddTargetUDPPacket(accessKey, status string, targetProxyBytes, proxyClientBytes int) {
	m.dataTargetProxyBytes.WithLabelValues("udp", accessKey, status).Add(float64(targetProxyBytes))
	m.dataProxyClientBytes.WithLabelValues("udp", accessKey, status).Add(float64(proxyClientBytes))
}

type ProxyMetrics struct {
	ClientProxy int64
	ProxyTarget int64
	TargetProxy int64
	ProxyClient int64
}

func (m *ProxyMetrics) add(other ProxyMetrics) {
	m.ClientProxy += other.ClientProxy
	m.ProxyTarget += other.ProxyTarget
	m.TargetProxy += other.TargetProxy
	m.ProxyClient += other.ProxyClient
}

type measuredConn struct {
	onet.DuplexConn
	io.WriterTo
	readCount *int64
	io.ReaderFrom
	writeCount *int64
}

func (c *measuredConn) Read(b []byte) (int, error) {
	n, err := c.DuplexConn.Read(b)
	*c.readCount += int64(n)
	return n, err
}

func (c *measuredConn) WriteTo(w io.Writer) (int64, error) {
	n, err := io.Copy(w, c.DuplexConn)
	*c.readCount += n
	return n, err
}

func (c *measuredConn) Write(b []byte) (int, error) {
	n, err := c.DuplexConn.Write(b)
	*c.writeCount += int64(n)
	return n, err
}

func (c *measuredConn) ReadFrom(r io.Reader) (int64, error) {
	n, err := io.Copy(c.DuplexConn, r)
	*c.writeCount += n
	return n, err
}

func MeasureConn(conn onet.DuplexConn, bytesSent, bytesRceived *int64) onet.DuplexConn {
	return &measuredConn{DuplexConn: conn, writeCount: bytesSent, readCount: bytesRceived}
}
<commit_msg>Make data direction a label<commit_after>// Copyright 2018 Jigsaw Operations LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package metrics

import (
	"io"
	"time"

	onet "github.com/Jigsaw-Code/outline-ss-server/net"
	"github.com/prometheus/client_golang/prometheus"
)

// ShadowsocksMetrics registers metrics for the Shadowsocks service.
type ShadowsocksMetrics interface {
	SetNumAccessKeys(numKeys int, numPorts int)
	AddClientUDPPacket(accessKey, status string, clientProxyBytes, proxyTargetBytes int)
	AddTargetUDPPacket(accessKey, status string, targetProxyBytes, proxyClientBytes int)
	AddOpenTCPConnection()
	AddClosedTCPConnection(accessKey, status string, data ProxyMetrics, duration time.Duration)
}

type shadowsocksMetrics struct {
	accessKeys           prometheus.Gauge
	ports                prometheus.Gauge
	tcpOpenConnections   prometheus.Counter
	tcpClosedConnections *prometheus.CounterVec
	// TODO: Define a time window for the duration summary (e.g. 1 hour)
	tcpConnectionDurationMs *prometheus.SummaryVec

	// TODO: Add per network/location metrics.
	// TODO: Add time to first byte.
	dataBytes *prometheus.CounterVec
}

func NewShadowsocksMetrics() ShadowsocksMetrics {
	m := &shadowsocksMetrics{
		accessKeys: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: "shadowsocks",
			Name:      "keys",
			Help:      "Count of access keys",
		}),
		ports: prometheus.NewGauge(prometheus.GaugeOpts{
			Namespace: "shadowsocks",
			Name:      "ports",
			Help:      "Count of open Shadowsocks ports",
		}),
		tcpOpenConnections: prometheus.NewCounter(prometheus.CounterOpts{
			Namespace: "shadowsocks",
			Subsystem: "tcp",
			Name:      "open_connections",
			Help:      "Count of open TCP connections",
		}),
		tcpClosedConnections: prometheus.NewCounterVec(prometheus.CounterOpts{
			Namespace: "shadowsocks",
			Subsystem: "tcp",
			Name:      "closed_connections",
			Help:      "Count of closed TCP connections",
		}, []string{"status", "access_key"}),
		tcpConnectionDurationMs: prometheus.NewSummaryVec(
			prometheus.SummaryOpts{
				Namespace:  "shadowsocks",
				Subsystem:  "tcp",
				Name:       "connection_duration_ms",
				Help:       "TCP connection duration distributions.",
				Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
			}, []string{"status", "access_key"}),
		dataBytes: prometheus.NewCounterVec(
			prometheus.CounterOpts{
				Namespace: "shadowsocks",
				Name:      "data_bytes",
				Help:      "Bytes tranferred from client to proxy.",
			}, []string{"dir", "proto", "status", "access_key"}),
	}
	// TODO: Is it possible to pass where to register the collectors?
	prometheus.MustRegister(m.accessKeys, m.ports, m.tcpOpenConnections, m.tcpClosedConnections, m.tcpConnectionDurationMs,
		m.dataBytes)
	return m
}

func (m *shadowsocksMetrics) SetNumAccessKeys(numKeys int, ports int) {
	m.accessKeys.Set(float64(numKeys))
	m.ports.Set(float64(ports))
}

func (m *shadowsocksMetrics) AddOpenTCPConnection() {
	m.tcpOpenConnections.Inc()
}

func (m *shadowsocksMetrics) AddClosedTCPConnection(accessKey, status string, data ProxyMetrics, duration time.Duration) {
	m.tcpClosedConnections.WithLabelValues(status, accessKey).Inc()
	m.tcpConnectionDurationMs.WithLabelValues(status, accessKey).Observe(duration.Seconds() * 1000)
	m.dataBytes.WithLabelValues("c>p", "tcp", status, accessKey).Add(float64(data.ClientProxy))
	m.dataBytes.WithLabelValues("p>t", "tcp", status, accessKey).Add(float64(data.ProxyTarget))
	m.dataBytes.WithLabelValues("p<t", "tcp", status, accessKey).Add(float64(data.TargetProxy))
	m.dataBytes.WithLabelValues("c<p", "tcp", status, accessKey).Add(float64(data.ProxyClient))
}

func (m *shadowsocksMetrics) AddClientUDPPacket(accessKey, status string, clientProxyBytes, proxyTargetBytes int) {
	m.dataBytes.WithLabelValues("c>p", "udp", status, accessKey).Add(float64(clientProxyBytes))
	m.dataBytes.WithLabelValues("p>t", "udp", status, accessKey).Add(float64(proxyTargetBytes))
}

func (m *shadowsocksMetrics) AddTargetUDPPacket(accessKey, status string, targetProxyBytes, proxyClientBytes int) {
	m.dataBytes.WithLabelValues("p<t", "udp", status, accessKey).Add(float64(targetProxyBytes))
	m.dataBytes.WithLabelValues("c<p", "udp", status, accessKey).Add(float64(proxyClientBytes))
}

type ProxyMetrics struct {
	ClientProxy int64
	ProxyTarget int64
	TargetProxy int64
	ProxyClient int64
}

func (m *ProxyMetrics) add(other ProxyMetrics) {
	m.ClientProxy += other.ClientProxy
	m.ProxyTarget += other.ProxyTarget
	m.TargetProxy += other.TargetProxy
	m.ProxyClient += other.ProxyClient
}

type measuredConn struct {
	onet.DuplexConn
	io.WriterTo
	readCount *int64
	io.ReaderFrom
	writeCount *int64
}

func (c *measuredConn) Read(b []byte) (int, error) {
	n, err := c.DuplexConn.Read(b)
	*c.readCount += int64(n)
	return n, err
}

func (c *measuredConn) WriteTo(w io.Writer) (int64, error) {
	n, err := io.Copy(w, c.DuplexConn)
	*c.readCount += n
	return n, err
}

func (c *measuredConn) Write(b []byte) (int, error) {
	n, err := c.DuplexConn.Write(b)
	*c.writeCount += int64(n)
	return n, err
}

func (c *measuredConn) ReadFrom(r io.Reader) (int64, error) {
	n, err := io.Copy(c.DuplexConn, r)
	*c.writeCount += n
	return n, err
}

func MeasureConn(conn onet.DuplexConn, bytesSent, bytesRceived *int64) onet.DuplexConn {
	return &measuredConn{DuplexConn: conn, writeCount: bytesSent, readCount: bytesRceived}
}
<|endoftext|>


<commit_before>package steamapi

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
)

// State represents the state of the tradeoffer, see constants
type State uint

const (
	// ETradeOfferStateCreated /!\ non steam status, used to know the TO has been created
	ETradeOfferStateCreated State = iota
	// ETradeOfferStateInvalid Invalid
	ETradeOfferStateInvalid
	// ETradeOfferStateActive This trade offer has been sent, neither party has acted on it yet.
	ETradeOfferStateActive
	// ETradeOfferStateAccepted The trade offer was accepted by the recipient and items were exchanged.
	ETradeOfferStateAccepted
	// ETradeOfferStateCountered The recipient made a counter offer
	ETradeOfferStateCountered
	// ETradeOfferStateExpired The trade offer was not accepted before the expiration date
	ETradeOfferStateExpired
	// ETradeOfferStateCanceled The sender cancelled the offer
	ETradeOfferStateCanceled
	// ETradeOfferStateDeclined The recipient declined the offer
	ETradeOfferStateDeclined
	// ETradeOfferStateInvalidItems Some of the items in the offer are no longer available
	// (indicated by the missing flag in the output)
	ETradeOfferStateInvalidItems
	// ETradeOfferStateEmailPending The offer hasn't been sent yet and is awaiting email confirmation
	ETradeOfferStateEmailPending
	// ETradeOfferStateEmailCanceled The receiver cancelled the offer via email
	ETradeOfferStateEmailCanceled
)

// CEconAsset represents an asset in steam web api
type CEconAsset struct {
	AppID          uint   `json:",string"`
	ContextID      uint64 `json:",string"`
	AssetID        uint64 `json:",string"`
	CurrencyID     uint64 `json:",string"`
	ClassID        uint64 `json:",string"`
	InstanceID     uint64 `json:",string"`
	Amount         uint64 `json:",string"`
	Missing        bool
	MarketHashName string
}

// CEconTradeOffer represent the to from the steam API
type CEconTradeOffer struct {
	TradeOfferID   uint64 `json:",string"`
	OtherAccountID uint64 `json:"accountid_other"`
	Message        string
	ExpirationTime uint32        `json:"expiration_time"`
	State          State         `json:"trade_offer_state"`
	ToGive         []*CEconAsset `json:"items_to_give"`
	ToReceive      []*CEconAsset `json:"items_to_receive"`
	IsOurs         bool          `json:"is_our_offer"`
	TimeCreated    uint32        `json:"time_created"`
	TimeUpdated    uint32        `json:"time_updated"`
	TradeID        uint64        `json:"tradeid,string"`
}

// CEconTradeOffers represent the list of different tradeoffers types
type CEconTradeOffers struct {
	Sent     []*CEconTradeOffer `json:"trade_offers_sent"`
	Received []*CEconTradeOffer `json:"trade_offers_received"`
}

type ieconGetTradeOffersResponse struct {
	Response struct {
		CEconTradeOffers
	}
}

// IEconGetTradeOffers retrieves a list of tradeoffers
func IEconGetTradeOffers(
	baseSteamAPIURL string,
	apiKey string,
	getSentOffers bool,
	getReceivedOffers bool,
	getDescriptions bool,
	activeOnly bool,
	historicalOnly bool,
	timeHistoricalCutoff int64,
) (*CEconTradeOffers, error) {

	querystring := url.Values{}
	querystring.Add("key", apiKey)
	querystring.Add("get_sent_offers", boolToStr(getSentOffers))
	querystring.Add("get_received_offers", boolToStr(getReceivedOffers))
	querystring.Add("get_descriptions", boolToStr(getDescriptions))
	querystring.Add("language", "en")
	querystring.Add("active_only", boolToStr(activeOnly))
	querystring.Add("historical_only", boolToStr(historicalOnly))
	querystring.Add("time_historical_cutoff", strconv.FormatInt(timeHistoricalCutoff, 10))

	resp, err := http.Get(baseSteamAPIURL + "/IEconService/GetTradeOffers/v0001?" + querystring.Encode())

	if err != nil {
		return nil, fmt.Errorf("tradeoffer IEconGetTradeOffers http.Get: error %v", err)
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("tradeoffer IEconGetTradeOffers http.Get: http status %v", resp.Status)
	}

	defer resp.Body.Close()

	tosResp := &ieconGetTradeOffersResponse{}
	err = json.NewDecoder(resp.Body).Decode(tosResp)

	if err != nil {
		return nil, fmt.Errorf("tradeoffer IEconGetTradeOffers Decode: error %v", err)
	}

	return &tosResp.Response.CEconTradeOffers, nil
}

type ieconGetTradeOfferResponse struct {
	Response struct {
		Offer        CEconTradeOffer
		Descriptions []ItemDescription
	}
}

// ItemDescription represents the details about the items unique w classid instanceid
type ItemDescription struct {
	AppID          uint   `json:"appid"`
	ClassID        uint64 `json:"classid,string"`
	InstanceID     uint64 `json:"instanceid,string"`
	MarketHashName string `json:"market_hash_name"`
	IconURL        string `json:"icon_url"`
	NameColor      string `json:"name_color"`
	Name           string `json:"name"`
}

func findMarketHashName(itemD []ItemDescription, appID uint, classID, instanceID uint64) string {
	for _, description := range itemD {
		if description.AppID == appID &&
			description.ClassID == classID &&
			description.InstanceID == instanceID {
			return description.MarketHashName
		}
	}

	return ""
}

// IEconGetTradeOffer retrieves details about a specific tradeoffer
func IEconGetTradeOffer(baseSteamAPIURL string, apiKey string, steamID uint64, tradeOfferID uint64) (
	*CEconTradeOffer, error,
) {

	querystring := url.Values{}
	querystring.Add("key", apiKey)
	querystring.Add("steamid", strconv.FormatUint(steamID, 10))
	querystring.Add("format", "json")
	querystring.Add("tradeofferid", strconv.FormatUint(tradeOfferID, 10))
	querystring.Add("language", "en")

	resp, err := http.Get(baseSteamAPIURL + "/IEconService/GetTradeOffer/v1?" + querystring.Encode())
	if err != nil {
		return nil, fmt.Errorf("tradeoffer IEconGetTradeOffer http.Get: error %v", err)
	}
	if resp.StatusCode != http.StatusOK {
		body, errBody := ioutil.ReadAll(resp.Body)
		return nil,
			fmt.Errorf("tradeoffer IEconGetTradeOffer: steam responded with a status %d with the message: %s (%v)",
				resp.StatusCode,
				body,
				errBody,
			)
	}

	defer resp.Body.Close()

	toResp := ieconGetTradeOfferResponse{}
	err = json.NewDecoder(resp.Body).Decode(&toResp)

	if err != nil {
		return nil, fmt.Errorf("tradeoffer IEconGetTradeOffer Decode: error %v", err)
	}

	for giveIndex, asset := range toResp.Response.Offer.ToGive {
		toResp.Response.Offer.ToGive[giveIndex].MarketHashName =
			findMarketHashName(toResp.Response.Descriptions, asset.AppID, asset.ClassID, asset.InstanceID)
	}

	for receiveIndex, asset := range toResp.Response.Offer.ToReceive {
		toResp.Response.Offer.ToReceive[receiveIndex].MarketHashName =
			findMarketHashName(toResp.Response.Descriptions, asset.AppID, asset.ClassID, asset.InstanceID)
	}

	return &toResp.Response.Offer, nil
}

// IEconActionTradeOffer declines a TO created by someone else
func IEconActionTradeOffer(baseSteamAPIURL string, action string, apiKey string, tradeOfferID uint64) error {

	if action != "Decline" && action != "Cancel" {
		return fmt.Errorf("tradeoffer IEconActionTradeOffer doesn't support %v action", action)
	}
	querystring := url.Values{}
	querystring.Add("key", apiKey)
	querystring.Add("tradeofferid", strconv.FormatUint(tradeOfferID, 10))

	resp, err := http.Get(
		baseSteamAPIURL + "/IEconService/" + action + "TradeOffer/v0001?" + querystring.Encode())

	if err != nil {
		return fmt.Errorf("tradeoffer IEconGetTradeOffer http.Get: error %v", err)
	}
	if resp.StatusCode != http.StatusOK {
		body, errBody := ioutil.ReadAll(resp.Body)
		return fmt.Errorf("tradeoffer IEcon%sTradeOffer: steam responded with a status %d with the message: %s (%v)",
			action,
			resp.StatusCode,
			body,
			errBody,
		)
	}

	err = resp.Body.Close()

	if err != nil {
		return fmt.Errorf("tradeoffer IEcon%sTradeOffer resp.Body.Close(): error %v", action, err)
	}

	return nil

}

func boolToStr(b bool) string {
	if b {
		return "1"
	}

	return "0"

}
<commit_msg>adding one more check for steam tradeoffer reliability<commit_after>package steamapi

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
)

// State represents the state of the tradeoffer, see constants
type State uint

const (
	// ETradeOfferStateCreated /!\ non steam status, used to know the TO has been created
	ETradeOfferStateCreated State = iota
	// ETradeOfferStateInvalid Invalid
	ETradeOfferStateInvalid
	// ETradeOfferStateActive This trade offer has been sent, neither party has acted on it yet.
	ETradeOfferStateActive
	// ETradeOfferStateAccepted The trade offer was accepted by the recipient and items were exchanged.
	ETradeOfferStateAccepted
	// ETradeOfferStateCountered The recipient made a counter offer
	ETradeOfferStateCountered
	// ETradeOfferStateExpired The trade offer was not accepted before the expiration date
	ETradeOfferStateExpired
	// ETradeOfferStateCanceled The sender cancelled the offer
	ETradeOfferStateCanceled
	// ETradeOfferStateDeclined The recipient declined the offer
	ETradeOfferStateDeclined
	// ETradeOfferStateInvalidItems Some of the items in the offer are no longer available
	// (indicated by the missing flag in the output)
	ETradeOfferStateInvalidItems
	// ETradeOfferStateEmailPending The offer hasn't been sent yet and is awaiting email confirmation
	ETradeOfferStateEmailPending
	// ETradeOfferStateEmailCanceled The receiver cancelled the offer via email
	ETradeOfferStateEmailCanceled
)

// CEconAsset represents an asset in steam web api
type CEconAsset struct {
	AppID          uint   `json:",string"`
	ContextID      uint64 `json:",string"`
	AssetID        uint64 `json:",string"`
	CurrencyID     uint64 `json:",string"`
	ClassID        uint64 `json:",string"`
	InstanceID     uint64 `json:",string"`
	Amount         uint64 `json:",string"`
	Missing        bool
	MarketHashName string
}

// CEconTradeOffer represent the to from the steam API
type CEconTradeOffer struct {
	TradeOfferID   uint64 `json:",string"`
	OtherAccountID uint64 `json:"accountid_other"`
	Message        string
	ExpirationTime uint32        `json:"expiration_time"`
	State          State         `json:"trade_offer_state"`
	ToGive         []*CEconAsset `json:"items_to_give"`
	ToReceive      []*CEconAsset `json:"items_to_receive"`
	IsOurs         bool          `json:"is_our_offer"`
	TimeCreated    uint32        `json:"time_created"`
	TimeUpdated    uint32        `json:"time_updated"`
	TradeID        uint64        `json:"tradeid,string"`
}

// CEconTradeOffers represent the list of different tradeoffers types
type CEconTradeOffers struct {
	Sent     []*CEconTradeOffer `json:"trade_offers_sent"`
	Received []*CEconTradeOffer `json:"trade_offers_received"`
}

type ieconGetTradeOffersResponse struct {
	Response struct {
		CEconTradeOffers
	}
}

// IEconGetTradeOffers retrieves a list of tradeoffers
func IEconGetTradeOffers(
	baseSteamAPIURL string,
	apiKey string,
	getSentOffers bool,
	getReceivedOffers bool,
	getDescriptions bool,
	activeOnly bool,
	historicalOnly bool,
	timeHistoricalCutoff int64,
) (*CEconTradeOffers, error) {

	querystring := url.Values{}
	querystring.Add("key", apiKey)
	querystring.Add("get_sent_offers", boolToStr(getSentOffers))
	querystring.Add("get_received_offers", boolToStr(getReceivedOffers))
	querystring.Add("get_descriptions", boolToStr(getDescriptions))
	querystring.Add("language", "en")
	querystring.Add("active_only", boolToStr(activeOnly))
	querystring.Add("historical_only", boolToStr(historicalOnly))
	querystring.Add("time_historical_cutoff", strconv.FormatInt(timeHistoricalCutoff, 10))

	resp, err := http.Get(baseSteamAPIURL + "/IEconService/GetTradeOffers/v0001?" + querystring.Encode())

	if err != nil {
		return nil, fmt.Errorf("tradeoffer IEconGetTradeOffers http.Get: error %v", err)
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("tradeoffer IEconGetTradeOffers http.Get: http status %v", resp.Status)
	}

	defer resp.Body.Close()

	tosResp := &ieconGetTradeOffersResponse{}
	err = json.NewDecoder(resp.Body).Decode(tosResp)

	if err != nil {
		return nil, fmt.Errorf("tradeoffer IEconGetTradeOffers Decode: error %v", err)
	}

	return &tosResp.Response.CEconTradeOffers, nil
}

type ieconGetTradeOfferResponse struct {
	Response struct {
		Offer        CEconTradeOffer
		Descriptions []ItemDescription
	}
}

// ItemDescription represents the details about the items unique w classid instanceid
type ItemDescription struct {
	AppID          uint   `json:"appid"`
	ClassID        uint64 `json:"classid,string"`
	InstanceID     uint64 `json:"instanceid,string"`
	MarketHashName string `json:"market_hash_name"`
	IconURL        string `json:"icon_url"`
	NameColor      string `json:"name_color"`
	Name           string `json:"name"`
}

func findMarketHashName(itemD []ItemDescription, appID uint, classID, instanceID uint64) string {
	for _, description := range itemD {
		if description.AppID == appID &&
			description.ClassID == classID &&
			description.InstanceID == instanceID {
			return description.MarketHashName
		}
	}

	return ""
}

// IEconGetTradeOffer retrieves details about a specific tradeoffer
func IEconGetTradeOffer(baseSteamAPIURL string, apiKey string, steamID uint64, tradeOfferID uint64) (
	*CEconTradeOffer, error,
) {

	querystring := url.Values{}
	querystring.Add("key", apiKey)
	querystring.Add("steamid", strconv.FormatUint(steamID, 10))
	querystring.Add("format", "json")
	querystring.Add("tradeofferid", strconv.FormatUint(tradeOfferID, 10))
	querystring.Add("language", "en")

	resp, err := http.Get(baseSteamAPIURL + "/IEconService/GetTradeOffer/v1?" + querystring.Encode())
	if err != nil {
		return nil, fmt.Errorf("tradeoffer IEconGetTradeOffer http.Get: error %v", err)
	}
	if resp.StatusCode != http.StatusOK {
		body, errBody := ioutil.ReadAll(resp.Body)
		return nil,
			fmt.Errorf("tradeoffer IEconGetTradeOffer: steam responded with a status %d with the message: %s (%v)",
				resp.StatusCode,
				body,
				errBody,
			)
	}

	defer resp.Body.Close()

	toResp := ieconGetTradeOfferResponse{}
	err = json.NewDecoder(resp.Body).Decode(&toResp)

	if err != nil {
		return nil, fmt.Errorf("tradeoffer IEconGetTradeOffer Decode: error %v", err)
	}

	// If the state is 0, it means there is a mistake
	if toResp.Response.Offer.State == 0 {
		body, errBody := ioutil.ReadAll(resp.Body)
		return nil,
			fmt.Errorf("tradeoffer IEconGetTradeOffer: steam responded with a status %d with the message: %s (%v)",
				resp.StatusCode,
				body,
				errBody,
			)
	}

	for giveIndex, asset := range toResp.Response.Offer.ToGive {
		toResp.Response.Offer.ToGive[giveIndex].MarketHashName =
			findMarketHashName(toResp.Response.Descriptions, asset.AppID, asset.ClassID, asset.InstanceID)
	}

	for receiveIndex, asset := range toResp.Response.Offer.ToReceive {
		toResp.Response.Offer.ToReceive[receiveIndex].MarketHashName =
			findMarketHashName(toResp.Response.Descriptions, asset.AppID, asset.ClassID, asset.InstanceID)
	}

	return &toResp.Response.Offer, nil
}

// IEconActionTradeOffer declines a TO created by someone else
func IEconActionTradeOffer(baseSteamAPIURL string, action string, apiKey string, tradeOfferID uint64) error {

	if action != "Decline" && action != "Cancel" {
		return fmt.Errorf("tradeoffer IEconActionTradeOffer doesn't support %v action", action)
	}
	querystring := url.Values{}
	querystring.Add("key", apiKey)
	querystring.Add("tradeofferid", strconv.FormatUint(tradeOfferID, 10))

	resp, err := http.Get(
		baseSteamAPIURL + "/IEconService/" + action + "TradeOffer/v0001?" + querystring.Encode())

	if err != nil {
		return fmt.Errorf("tradeoffer IEconGetTradeOffer http.Get: error %v", err)
	}
	if resp.StatusCode != http.StatusOK {
		body, errBody := ioutil.ReadAll(resp.Body)
		return fmt.Errorf("tradeoffer IEcon%sTradeOffer: steam responded with a status %d with the message: %s (%v)",
			action,
			resp.StatusCode,
			body,
			errBody,
		)
	}

	err = resp.Body.Close()

	if err != nil {
		return fmt.Errorf("tradeoffer IEcon%sTradeOffer resp.Body.Close(): error %v", action, err)
	}

	return nil

}

func boolToStr(b bool) string {
	if b {
		return "1"
	}

	return "0"

}
<|endoftext|>


<commit_before>package middleware

import (
	"fmt"
	"net/http"

	"github.com/labstack/echo"
	coreMiddleware "github.com/labstack/echo/middleware"
)

// LockedDownCORSWithConfig is good
func LockedDownCORSWithConfig(config coreMiddleware.CORSConfig) echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		CORSWithConfig := coreMiddleware.CORSWithConfig(config)
		CORSWithConfigHandler := CORSWithConfig(next)

		return func(c echo.Context) error {

			req := c.Request()
			origin := req.Header.Get(echo.HeaderOrigin)
			allowOrigin := ""

			// Check allowed origins
			for _, o := range config.AllowOrigins {
				if o == "*" && config.AllowCredentials {
					allowOrigin = origin
					break
				}
				if o == "*" || o == origin {
					allowOrigin = o
					break
				}
			}

			if allowOrigin == "" {
				fmt.Printf("Rejected request from origin %s", origin)
				return c.NoContent(http.StatusForbidden)
			}

			return CORSWithConfigHandler(c)

		}
	}
}
<commit_msg>Removed locked-down CORS because it doesn't work<commit_after><|endoftext|>


<commit_before>package ts

import br "github.com/32bitkid/bitreader"

func NewDemuxer(reader br.Reader32) Demuxer {
	return &tsDemuxer{
		reader:    reader,
		skipUntil: alwaysTrueTester,
		takeWhile: alwaysTrueTester,
	}
}

type Demuxer interface {
	Where(PacketTester) PacketChannel
	Go() <-chan bool
	Err() error

	SkipUntil(PacketTester) Demuxer
	TakeWhile(PacketTester) Demuxer
}

type conditionalChannel struct {
	test    PacketTester
	channel chan<- *Packet
}

type tsDemuxer struct {
	reader             br.Reader32
	registeredChannels []conditionalChannel
	lastErr            error
	skipUntil          PacketTester
	takeWhile          PacketTester
}

func (tsd *tsDemuxer) Where(test PacketTester) PacketChannel {
	channel := make(chan *Packet)
	tsd.registeredChannels = append(tsd.registeredChannels, conditionalChannel{test, channel})
	return channel
}

func (tsd *tsDemuxer) SkipUntil(skipUntil PacketTester) Demuxer {
	tsd.skipUntil = skipUntil
	return tsd
}

func (tsd *tsDemuxer) TakeWhile(takeWhile PacketTester) Demuxer {
	tsd.takeWhile = takeWhile
	return tsd
}

func (tsd *tsDemuxer) Go() <-chan bool {

	done := make(chan bool, 1)
	var skipping = true
	var skipUntil = tsd.skipUntil
	var takeWhile = tsd.takeWhile

	go func() {

		defer func() { done <- true }()
		for _, item := range tsd.registeredChannels {
			defer close(item.channel)
		}

		for true {
			p, err := ReadPacket(tsd.reader)

			if err != nil {
				tsd.lastErr = err
				done <- true
				return
			}

			if skipping {
				if !skipUntil(p) {
					continue
				} else {
					skipping = false
				}
			} else {
				if !takeWhile(p) {
					return
				}
			}

			for _, item := range tsd.registeredChannels {
				if item.test(p) {
					item.channel <- p
				}
			}
		}
	}()

	return done
}

func (tsd *tsDemuxer) Err() error {
	return tsd.lastErr
}
<commit_msg>Defer closing all registered channels at once<commit_after>package ts

import br "github.com/32bitkid/bitreader"

func NewDemuxer(reader br.Reader32) Demuxer {
	return &tsDemuxer{
		reader:    reader,
		skipUntil: alwaysTrueTester,
		takeWhile: alwaysTrueTester,
	}
}

type Demuxer interface {
	Where(PacketTester) PacketChannel
	Go() <-chan bool
	Err() error

	SkipUntil(PacketTester) Demuxer
	TakeWhile(PacketTester) Demuxer
}

type conditionalChannel struct {
	test    PacketTester
	channel chan<- *Packet
}

type tsDemuxer struct {
	reader             br.Reader32
	registeredChannels []conditionalChannel
	lastErr            error
	skipUntil          PacketTester
	takeWhile          PacketTester
}

func (tsd *tsDemuxer) Where(test PacketTester) PacketChannel {
	channel := make(chan *Packet)
	tsd.registeredChannels = append(tsd.registeredChannels, conditionalChannel{test, channel})
	return channel
}

func (tsd *tsDemuxer) SkipUntil(skipUntil PacketTester) Demuxer {
	tsd.skipUntil = skipUntil
	return tsd
}

func (tsd *tsDemuxer) TakeWhile(takeWhile PacketTester) Demuxer {
	tsd.takeWhile = takeWhile
	return tsd
}

func (tsd *tsDemuxer) Go() <-chan bool {

	done := make(chan bool, 1)
	var skipping = true
	var skipUntil = tsd.skipUntil
	var takeWhile = tsd.takeWhile

	go func() {

		defer func() { done <- true }()
		defer func() {
			for _, item := range tsd.registeredChannels {
				close(item.channel)
			}
		}()

		for true {
			p, err := ReadPacket(tsd.reader)

			if err != nil {
				tsd.lastErr = err
				done <- true
				return
			}

			if skipping {
				if !skipUntil(p) {
					continue
				} else {
					skipping = false
				}
			} else {
				if !takeWhile(p) {
					return
				}
			}

			for _, item := range tsd.registeredChannels {
				if item.test(p) {
					item.channel <- p
				}
			}
		}
	}()

	return done
}

func (tsd *tsDemuxer) Err() error {
	return tsd.lastErr
}
<|endoftext|>


<commit_before>package http_api

import (
	"encoding/hex"
	"fmt"
	"net/http"
	"testing"

	"github.com/jarcoal/httpmock"
	"github.com/uniqush/uniqush-push/push"
	"github.com/uniqush/uniqush-push/srv/apns/common"
)

const (
	authToken = "test_auth_token"
	keyFile   = "../apns-test/localhost.p8"
	keyID     = "FD8789SD9"
	teamID    = "JVNS20943"
	bundleID  = "com.example.test"
)

var (
	pushServiceProvider = &push.PushServiceProvider{
		push.PushPeer{
			VolatileData: map[string]string{
				"addr": "https://api.development.push.apple.com",
			},
			FixedData: map[string]string{
				"p8":       keyFile,
				"keyid":    keyID,
				"teamid":   teamID,
				"bundleid": bundleID,
			},
		},
	}
	devToken = []byte("test_device_token")
	payload  = []byte(`{"alert":"test_message"}`)
)

type MockJWTManager struct{}

func (*MockJWTManager) GenerateToken() (string, error) {
	return authToken, nil
}

func TestAddRequest(t *testing.T) {
	httpmock.Activate()
	defer httpmock.DeactivateAndReset()

	errChan := make(chan push.PushError)
	resChan := make(chan *common.APNSResult, 1)

	request := &common.PushRequest{
		PSP:       pushServiceProvider,
		Devtokens: [][]byte{devToken},
		Payload:   payload,
		ErrChan:   errChan,
		ResChan:   resChan,
	}

	apiURL := fmt.Sprintf("%s/3/device/%s", request.PSP.VolatileData["addr"], hex.EncodeToString(devToken))
	httpmock.RegisterResponder("POST", apiURL, func(r *http.Request) (*http.Response, error) {
		// Return empty body
		return httpmock.NewBytesResponse(http.StatusOK, nil), nil
	})

	NewRequestProcessor().AddRequest(request)

	for err := range errChan {
		if err != nil {
			t.Fatal("Error processing push request,", err)
		}
	}
}

func TestGetMaxPayloadSize(t *testing.T) {
	maxPayloadSize := NewRequestProcessor().GetMaxPayloadSize()
	if maxPayloadSize != 4096 {
		t.Fatalf("Wrong max payload, expected `4096`, got `%d`", maxPayloadSize)
	}
}
<commit_msg>Add fail scenario<commit_after>package http_api

import (
	"encoding/hex"
	"fmt"
	"net/http"
	"testing"

	"github.com/jarcoal/httpmock"
	"github.com/uniqush/uniqush-push/push"
	"github.com/uniqush/uniqush-push/srv/apns/common"
)

const (
	authToken = "test_auth_token"
	keyFile   = "../apns-test/localhost.p8"
	keyID     = "FD8789SD9"
	teamID    = "JVNS20943"
	bundleID  = "com.example.test"
)

var (
	pushServiceProvider = &push.PushServiceProvider{
		push.PushPeer{
			VolatileData: map[string]string{
				"addr": "https://api.development.push.apple.com",
			},
			FixedData: map[string]string{
				"p8":       keyFile,
				"keyid":    keyID,
				"teamid":   teamID,
				"bundleid": bundleID,
			},
		},
	}
	devToken = []byte("test_device_token")
	payload  = []byte(`{"alert":"test_message"}`)
	apiURL   = fmt.Sprintf("%s/3/device/%s", pushServiceProvider.VolatileData["addr"], hex.EncodeToString(devToken))
)

type MockJWTManager struct{}

func (*MockJWTManager) GenerateToken() (string, error) {
	return authToken, nil
}

func TestAddRequestPushSuccessful(t *testing.T) {
	httpmock.Activate()
	defer httpmock.DeactivateAndReset()

	errChan := make(chan push.PushError)
	resChan := make(chan *common.APNSResult, 1)

	request := &common.PushRequest{
		PSP:       pushServiceProvider,
		Devtokens: [][]byte{devToken},
		Payload:   payload,
		ErrChan:   errChan,
		ResChan:   resChan,
	}

	httpmock.RegisterResponder("POST", apiURL, func(r *http.Request) (*http.Response, error) {
		// Return empty body
		return httpmock.NewBytesResponse(http.StatusOK, nil), nil
	})

	NewRequestProcessor().AddRequest(request)

	for err := range errChan {
		if err != nil {
			t.Fatal("Error processing push request,", err)
		}
	}
}

func TestAddRequestPushFailConnectionError(t *testing.T) {
	httpmock.Activate()
	defer httpmock.DeactivateAndReset()

	errChan := make(chan push.PushError)
	resChan := make(chan *common.APNSResult, 1)

	request := &common.PushRequest{
		PSP:       pushServiceProvider,
		Devtokens: [][]byte{devToken},
		Payload:   payload,
		ErrChan:   errChan,
		ResChan:   resChan,
	}

	httpmock.RegisterResponder("POST", apiURL, func(r *http.Request) (*http.Response, error) {
		return nil, fmt.Errorf("No connection")
	})

	NewRequestProcessor().AddRequest(request)

	for err := range errChan {
		switch err := err.(type) {
		case *push.ConnectionError:
		default:
			t.Fatal("Expected Connection error, got", err)
		}
	}
}

func TestAddRequestPushFailNotificationError(t *testing.T) {
	httpmock.Activate()
	defer httpmock.DeactivateAndReset()

	errChan := make(chan push.PushError)
	resChan := make(chan *common.APNSResult, 1)

	request := &common.PushRequest{
		PSP:       pushServiceProvider,
		Devtokens: [][]byte{devToken},
		Payload:   payload,
		ErrChan:   errChan,
		ResChan:   resChan,
	}

	httpmock.RegisterResponder("POST", apiURL, func(r *http.Request) (*http.Response, error) {
		response := &APNSErrorResponse{
			Reason: "BadDeviceToken",
		}
		return httpmock.NewJsonResponse(http.StatusBadRequest, response)
	})

	NewRequestProcessor().AddRequest(request)

	for err := range errChan {
		switch err := err.(type) {
		case *push.BadNotification:
		default:
			t.Fatal("Expected BadNotification error, got", err)
		}
	}
}

func TestGetMaxPayloadSize(t *testing.T) {
	maxPayloadSize := NewRequestProcessor().GetMaxPayloadSize()
	if maxPayloadSize != 4096 {
		t.Fatalf("Wrong max payload, expected `4096`, got `%d`", maxPayloadSize)
	}
}
<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2016 ZiRo

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

package main

import "crypto/sha256"
import "github.com/gopherjs/gopherjs/js"

const (
	SIZESHIFT uint64 = 20
	PROOFSIZE uint64 = 42
	SIZE      uint64 = 1 << SIZESHIFT
	HALFSIZE  uint64 = SIZE / 2
	NODEMASK  uint64 = HALFSIZE - 1
)

type Cuckoo struct {
	v [4]uint64
	key []byte
}

func u8(b byte) uint64 {
	return (uint64)(b) & 0xff
}

func u8to64(p [sha256.Size]byte, i int) uint64 {
	return u8(p[i]) | u8(p[i+1])<<8 |
		u8(p[i+2])<<16 | u8(p[i+3])<<24 |
		u8(p[i+4])<<32 | u8(p[i+5])<<40 |
		u8(p[i+6])<<48 | u8(p[i+7])<<56
}

func NewCuckoo(header []byte) *Cuckoo {
	hdrkey := sha256.Sum256(header)

	return NewCuckooSHA(hdrkey)
}

func NewCuckooSHA(hdrkey [sha256.Size]byte) *Cuckoo {
	self := new(Cuckoo)
	k0 := u8to64(hdrkey, 0)
	k1 := u8to64(hdrkey, 8)
	self.v[0] = k0 ^ 0x736f6d6570736575
	self.v[1] = k1 ^ 0x646f72616e646f6d
	self.v[2] = k0 ^ 0x6c7967656e657261
	self.v[3] = k1 ^ 0x7465646279746573
	self.key = hdrkey[:]

	return self
}

type Edge struct {
	U uint64
	V uint64
}

func (self *Edge) HashCode() int {
	return int(self.U) ^ int(self.V)
}

func (self *Cuckoo) Sipedge(nonce uint64) *Edge {
	return &Edge{self.Sipnode(nonce, 0), self.Sipnode(nonce, 1)}
}

func (self *Cuckoo) siphash24(nonce uint64) uint64 {
	return siphash24_js(self.key, nonce)
}

var sh  *js.Object = js.Global.Call("require", "./siphash-lib.js")

func siphash24_js(hdrkey []byte, nonce uint64) uint64 {
	arr := sh.Call("hash", hdrkey, 0, nonce)
	high := arr.Index(0).Uint64();
	low := arr.Index(1).Uint64();

	return (high << 32) | low;
}

// generate edge in cuckoo graph
func (self *Cuckoo) Sipnode(nonce uint64, uorv uint32) uint64 {
	return self.siphash24(2*nonce+uint64(uorv)) & NODEMASK
}

// verify that (ascending) nonces, all less than easiness, form a cycle in graph
func (self *Cuckoo) Verify(nonces []uint64, easiness uint64) bool {
	us := make([]uint64, PROOFSIZE)
	vs := make([]uint64, PROOFSIZE)
	i := 0
	var n uint64

	for n = 0; n < PROOFSIZE; n++ {
		if nonces[n] >= easiness || (n != 0 && nonces[n] <= nonces[n-1]) {
			return false
		}
		us[n] = self.Sipnode(nonces[n], 0)
		vs[n] = self.Sipnode(nonces[n], 1)
	}

	loop := true
	for loop { // follow cycle until we return to i==0; n edges left to visit
		j := i
		for k := 0; uint64(k) < PROOFSIZE; k++ { // find unique other j with same vs[j]
			if k != i && vs[k] == vs[i] {
				if j != i {
					return false
				}
				j = k
			}
		}
		if j == i {
			return false
		}
		i = j
		for k := 0; uint64(k) < PROOFSIZE; k++ { // find unique other i with same us[i]
			if k != j && us[k] == us[j] {
				if i != j {
					return false
				}
				i = k
			}
		}
		if i == j {
			return false
		}
		n -= 2
		loop = (i != 0)
	}
	return n == 0
}
<commit_msg>try fixing js for browser<commit_after>/*
The MIT License (MIT)

Copyright (c) 2016 ZiRo

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

package main

import "crypto/sha256"
import "github.com/gopherjs/gopherjs/js"

const (
	SIZESHIFT uint64 = 20
	PROOFSIZE uint64 = 42
	SIZE      uint64 = 1 << SIZESHIFT
	HALFSIZE  uint64 = SIZE / 2
	NODEMASK  uint64 = HALFSIZE - 1
)

type Cuckoo struct {
	v [4]uint64
	key []byte
}

func u8(b byte) uint64 {
	return (uint64)(b) & 0xff
}

func u8to64(p [sha256.Size]byte, i int) uint64 {
	return u8(p[i]) | u8(p[i+1])<<8 |
		u8(p[i+2])<<16 | u8(p[i+3])<<24 |
		u8(p[i+4])<<32 | u8(p[i+5])<<40 |
		u8(p[i+6])<<48 | u8(p[i+7])<<56
}

func NewCuckoo(header []byte) *Cuckoo {
	hdrkey := sha256.Sum256(header)

	return NewCuckooSHA(hdrkey)
}

func NewCuckooSHA(hdrkey [sha256.Size]byte) *Cuckoo {
	self := new(Cuckoo)
	k0 := u8to64(hdrkey, 0)
	k1 := u8to64(hdrkey, 8)
	self.v[0] = k0 ^ 0x736f6d6570736575
	self.v[1] = k1 ^ 0x646f72616e646f6d
	self.v[2] = k0 ^ 0x6c7967656e657261
	self.v[3] = k1 ^ 0x7465646279746573
	self.key = hdrkey[:]

	return self
}

type Edge struct {
	U uint64
	V uint64
}

func (self *Edge) HashCode() int {
	return int(self.U) ^ int(self.V)
}

func (self *Cuckoo) Sipedge(nonce uint64) *Edge {
	return &Edge{self.Sipnode(nonce, 0), self.Sipnode(nonce, 1)}
}

func (self *Cuckoo) siphash24(nonce uint64) uint64 {
	return siphash24_js(self.key, nonce)
}

var sh  *js.Object = js.Global.Get("SipHash")

func siphash24_js(hdrkey []byte, nonce uint64) uint64 {
	arr := sh.Call("hash", hdrkey, 0, nonce)
	high := arr.Index(0).Uint64();
	low := arr.Index(1).Uint64();

	return (high << 32) | low;
}

// generate edge in cuckoo graph
func (self *Cuckoo) Sipnode(nonce uint64, uorv uint32) uint64 {
	return self.siphash24(2*nonce+uint64(uorv)) & NODEMASK
}

// verify that (ascending) nonces, all less than easiness, form a cycle in graph
func (self *Cuckoo) Verify(nonces []uint64, easiness uint64) bool {
	us := make([]uint64, PROOFSIZE)
	vs := make([]uint64, PROOFSIZE)
	i := 0
	var n uint64

	for n = 0; n < PROOFSIZE; n++ {
		if nonces[n] >= easiness || (n != 0 && nonces[n] <= nonces[n-1]) {
			return false
		}
		us[n] = self.Sipnode(nonces[n], 0)
		vs[n] = self.Sipnode(nonces[n], 1)
	}

	loop := true
	for loop { // follow cycle until we return to i==0; n edges left to visit
		j := i
		for k := 0; uint64(k) < PROOFSIZE; k++ { // find unique other j with same vs[j]
			if k != i && vs[k] == vs[i] {
				if j != i {
					return false
				}
				j = k
			}
		}
		if j == i {
			return false
		}
		i = j
		for k := 0; uint64(k) < PROOFSIZE; k++ { // find unique other i with same us[i]
			if k != j && us[k] == us[j] {
				if i != j {
					return false
				}
				i = k
			}
		}
		if i == j {
			return false
		}
		n -= 2
		loop = (i != 0)
	}
	return n == 0
}
<|endoftext|>


<commit_before>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package common

import (
	"time"

	"launchpad.net/loggo"

	"launchpad.net/juju-core/environs"
	"launchpad.net/juju-core/environs/config"
	"launchpad.net/juju-core/state"
	"launchpad.net/juju-core/state/api"
	"launchpad.net/juju-core/state/api/params"
)

var logger = loggo.GetLogger("juju.state.apiserver.common")

// AddressAndCertGetter can be used to find out
// state server addresses and the CA public certificate.
type AddressAndCertGetter interface {
	Addresses() ([]string, error)
	APIAddresses() ([]string, error)
	CACert() []byte
}

// Addresser implements a common set of methods for getting state and
// API server addresses, and the CA certificate used to authenticate
// them.
type Addresser struct {
	getter AddressAndCertGetter
}

// NewAddresser returns a new Addresser that uses the given
// st value to fetch its addresses.
func NewAddresser(getter AddressAndCertGetter) *Addresser {
	return &Addresser{getter}
}

// StateAddresses returns the list of addresses used to connect to the state.
//
// TODO(dimitern): Remove this once we have a way to get state/API
// public addresses from state.
// BUG(lp:1205371): This is temporary, until the Addresser worker
// lands and we can take the addresses of all machines with
// JobManageState.
func (a *Addresser) StateAddresses() (params.StringsResult, error) {
	addrs, err := a.getter.Addresses()
	if err != nil {
		return params.StringsResult{}, err
	}
	return params.StringsResult{
		Result: addrs,
	}, nil
}

// APIAddresses returns the list of addresses used to connect to the API.
//
// TODO(dimitern): Remove this once we have a way to get state/API
// public addresses from state.
// BUG(lp:1205371): This is temporary, until the Addresser worker
// lands and we can take the addresses of all machines with
// JobManageState.
func (a *Addresser) APIAddresses() (params.StringsResult, error) {
	addrs, err := a.getter.APIAddresses()
	if err != nil {
		return params.StringsResult{}, err
	}
	return params.StringsResult{
		Result: addrs,
	}, nil
}

// CACert returns the certificate used to validate the state connection.
func (a *Addresser) CACert() params.BytesResult {
	return params.BytesResult{
		Result: a.getter.CACert(),
	}
}

type APIAddresser struct {
	st    EnvironConfigAndCertGetter
	cache map[string]interface{}
}

func (a *APIAddresser) getEnvironStateInfo() (*state.Info, *api.Info, error) {
	return getEnvironStateInfo(a.st, a.cache)
}

func (a *APIAddresser) APIAddresses() (params.StringsResult, error) {
	_, apiInfo, err := a.getEnvironStateInfo()
	if err != nil {
		return params.StringsResult{}, err
	}
	return params.StringsResult{
		Result: apiInfo.Addrs,
	}, nil
}
<commit_msg>Fix an unused import<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package common

import (
	"launchpad.net/loggo"

	"launchpad.net/juju-core/environs"
	"launchpad.net/juju-core/environs/config"
	"launchpad.net/juju-core/state"
	"launchpad.net/juju-core/state/api"
	"launchpad.net/juju-core/state/api/params"
)

var logger = loggo.GetLogger("juju.state.apiserver.common")

// AddressAndCertGetter can be used to find out
// state server addresses and the CA public certificate.
type AddressAndCertGetter interface {
	Addresses() ([]string, error)
	APIAddresses() ([]string, error)
	CACert() []byte
}

// Addresser implements a common set of methods for getting state and
// API server addresses, and the CA certificate used to authenticate
// them.
type Addresser struct {
	getter AddressAndCertGetter
}

// NewAddresser returns a new Addresser that uses the given
// st value to fetch its addresses.
func NewAddresser(getter AddressAndCertGetter) *Addresser {
	return &Addresser{getter}
}

// StateAddresses returns the list of addresses used to connect to the state.
//
// TODO(dimitern): Remove this once we have a way to get state/API
// public addresses from state.
// BUG(lp:1205371): This is temporary, until the Addresser worker
// lands and we can take the addresses of all machines with
// JobManageState.
func (a *Addresser) StateAddresses() (params.StringsResult, error) {
	addrs, err := a.getter.Addresses()
	if err != nil {
		return params.StringsResult{}, err
	}
	return params.StringsResult{
		Result: addrs,
	}, nil
}

// APIAddresses returns the list of addresses used to connect to the API.
//
// TODO(dimitern): Remove this once we have a way to get state/API
// public addresses from state.
// BUG(lp:1205371): This is temporary, until the Addresser worker
// lands and we can take the addresses of all machines with
// JobManageState.
func (a *Addresser) APIAddresses() (params.StringsResult, error) {
	addrs, err := a.getter.APIAddresses()
	if err != nil {
		return params.StringsResult{}, err
	}
	return params.StringsResult{
		Result: addrs,
	}, nil
}

// CACert returns the certificate used to validate the state connection.
func (a *Addresser) CACert() params.BytesResult {
	return params.BytesResult{
		Result: a.getter.CACert(),
	}
}

type APIAddresser struct {
	st    EnvironConfigAndCertGetter
	cache map[string]interface{}
}

func (a *APIAddresser) getEnvironStateInfo() (*state.Info, *api.Info, error) {
	return getEnvironStateInfo(a.st, a.cache)
}

func (a *APIAddresser) APIAddresses() (params.StringsResult, error) {
	_, apiInfo, err := a.getEnvironStateInfo()
	if err != nil {
		return params.StringsResult{}, err
	}
	return params.StringsResult{
		Result: apiInfo.Addrs,
	}, nil
}
<|endoftext|>


<commit_before>package gdrj

import (
	// "github.com/eaciit/toolkit"
	"github.com/eaciit/orm/v1"
	//"github.com/eaciit/dbox"
	"time"
)

type LedgerTrx struct {
	orm.ModelBase `json:"-" bson:"-"`
	ID            string `json:"_id" bson:"_id"`
	Year          int
	Month         time.Month
	Qtr           int
	Data          time.Time
	PeriodID      string
	CompanyCode   string
	PCID          string
	CCID          string
	LedgerAccount string
	Value         float64
}

func (t *LedgerTrx) RecordID() interface{} {
	return t.ID
}

func (t *LedgerTrx) TableName() string {
	return "LedgerTrx"
}

type Date struct {
	ID      string
	Date    time.Time
	Month   time.Month
	Quarter int
	Year    int
}

type LedgerSummary struct {
	ID       string
	PC       *ProfitCenter
	CC       *CostCenter
    CompanyCode string
    LedgerAccount string
	Customer *Customer
	Product  *Product
	Date     *Date
	Value1, Value2, Value3 float64
}

func (s *LedgerSummary) RecordID() interface{} {
	return toolkit.Sprintf("%d_%d_%s_%s", s.Date.Year, s.Date.Month, s.CompanyCode, s.LedgerAccount)
}

func (s *LedgerSummary) TableName() string {
	return "LedgerSummary"
}
<commit_msg>no message<commit_after>package gdrj

import (
	// "github.com/eaciit/toolkit"
	"github.com/eaciit/orm/v1"
	//"github.com/eaciit/dbox"
	"time"
)

type LedgerTrx struct {
	orm.ModelBase `json:"-" bson:"-"`
	ID            string `json:"_id" bson:"_id"`
	Year          int
	Month         time.Month
	Qtr           int
	Data          time.Time
	PeriodID      string
	CompanyCode   string
	PCID          string
	CCID          string
	LedgerAccount string
	Value         float64
}

func (t *LedgerTrx) RecordID() interface{} {
	return t.ID
}

func (t *LedgerTrx) TableName() string {
	return "LedgerTrx"
}

type Date struct {
	ID      string
	Date    time.Time
	Month   time.Month
	Quarter int
	Year    int
}
<|endoftext|>


<commit_before>package model

// NewTombstone returns new DataDefinition
// Tombstones are DataDefinition with Status = 2
// and empty byte buffer containing the image data
func NewTombstone(df *DataDefinition) *DataDefinition {
	df.Status = 2
	df.Buf = []byte("")
	return df
}
<commit_msg>change tombstone status<commit_after>package model

// NewTombstone returns new DataDefinition
// Tombstones are DataDefinition with Status = DataDefinitionRemoved
// and empty byte buffer containing the image data
func NewTombstone(df *DataDefinition) *DataDefinition {
	df.Status = DataDefinitionRemoved
	df.Buf = []byte("")
	return df
}
<|endoftext|>


<commit_before>// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package service // import "go.opentelemetry.io/collector/service"

import (
	"context"
	"fmt"
	"regexp"
	"strings"
	"sync"

	"go.uber.org/multierr"

	"go.opentelemetry.io/collector/component"
	"go.opentelemetry.io/collector/config"
	"go.opentelemetry.io/collector/config/configmapprovider"
	"go.opentelemetry.io/collector/config/configunmarshaler"
	"go.opentelemetry.io/collector/config/experimental/configsource"
)

// ConfigProvider provides the service configuration.
//
// The typical usage is the following:
//
//		cfgProvider.Get(...)
//		cfgProvider.Watch() // wait for an event.
//		cfgProvider.Get(...)
//		cfgProvider.Watch() // wait for an event.
//		// repeat Get/Watch cycle until it is time to shut down the Collector process.
//		cfgProvider.Shutdown()
type ConfigProvider interface {
	// Get returns the service configuration, or error otherwise.
	//
	// Should never be called concurrently with itself, Watch or Shutdown.
	Get(ctx context.Context, factories component.Factories) (*config.Config, error)

	// Watch blocks until any configuration change was detected or an unrecoverable error
	// happened during monitoring the configuration changes.
	//
	// Error is nil if the configuration is changed and needs to be re-fetched. Any non-nil
	// error indicates that there was a problem with watching the config changes.
	//
	// Should never be called concurrently with itself or Get.
	Watch() <-chan error

	// Shutdown signals that the provider is no longer in use and the that should close
	// and release any resources that it may have created.
	//
	// This function must terminate the Watch channel.
	//
	// Should never be called concurrently with itself or Get.
	Shutdown(ctx context.Context) error
}

type configProvider struct {
	locations          []string
	configMapProviders map[string]configmapprovider.Provider
	cfgMapConverters   []config.MapConverterFunc
	configUnmarshaler  configunmarshaler.ConfigUnmarshaler

	sync.Mutex
	closer  configmapprovider.CloseFunc
	watcher chan error
}

// MustNewConfigProvider returns a new ConfigProvider that provides the configuration:
// * Retrieve the config.Map by merging all retrieved maps from all the configmapprovider.Provider in order.
// * Then applies all the ConfigMapConverterFunc in the given order.
// * Then unmarshalls the final config.Config using the given configunmarshaler.ConfigUnmarshaler.
//
// The `configMapProviders` is a map of pairs <scheme,Provider>.
func MustNewConfigProvider(
	locations []string,
	configMapProviders map[string]configmapprovider.Provider,
	cfgMapConverters []config.MapConverterFunc,
	configUnmarshaler configunmarshaler.ConfigUnmarshaler) ConfigProvider {
	// Safe copy, ensures the slice cannot be changed from the caller.
	locationsCopy := make([]string, len(locations))
	copy(locationsCopy, locations)
	return &configProvider{
		locations:          locationsCopy,
		configMapProviders: configMapProviders,
		cfgMapConverters:   cfgMapConverters,
		configUnmarshaler:  configUnmarshaler,
		watcher:            make(chan error, 1),
	}
}

// MustNewDefaultConfigProvider returns the default ConfigProvider, and it creates configuration from a file
// defined by the given configFile and overwrites fields using properties.
func MustNewDefaultConfigProvider(configLocations []string, properties []string) ConfigProvider {
	return MustNewConfigProvider(
		configLocations,
		map[string]configmapprovider.Provider{
			"file": configmapprovider.NewFile(),
			"env":  configmapprovider.NewEnv(),
		},
		[]config.MapConverterFunc{
			configmapprovider.NewOverwritePropertiesConverter(properties),
			configmapprovider.NewExpandConverter(),
		},
		configunmarshaler.NewDefault())
}

func (cm *configProvider) Get(ctx context.Context, factories component.Factories) (*config.Config, error) {
	// First check if already an active watching, close that if any.
	if err := cm.closeIfNeeded(ctx); err != nil {
		return nil, fmt.Errorf("cannot close previous watch: %w", err)
	}

	ret, err := cm.mergeRetrieve(ctx)
	if err != nil {
		return nil, fmt.Errorf("cannot retrieve the configuration: %w", err)
	}
	cm.closer = ret.CloseFunc

	// Apply all converters.
	for _, cfgMapConv := range cm.cfgMapConverters {
		if err = cfgMapConv(ctx, ret.Map); err != nil {
			return nil, fmt.Errorf("cannot convert the config.Map: %w", err)
		}
	}

	var cfg *config.Config
	if cfg, err = cm.configUnmarshaler.Unmarshal(ret.Map, factories); err != nil {
		return nil, fmt.Errorf("cannot unmarshal the configuration: %w", err)
	}

	if err = cfg.Validate(); err != nil {
		return nil, fmt.Errorf("invalid configuration: %w", err)
	}

	return cfg, nil
}

func (cm *configProvider) Watch() <-chan error {
	return cm.watcher
}

func (cm *configProvider) onChange(event *configmapprovider.ChangeEvent) {
	// TODO: Remove check for configsource.ErrSessionClosed when providers updated to not call onChange when closed.
	if event.Error != configsource.ErrSessionClosed {
		cm.watcher <- event.Error
	}
}

func (cm *configProvider) closeIfNeeded(ctx context.Context) error {
	if cm.closer != nil {
		return cm.closer(ctx)
	}
	return nil
}

func (cm *configProvider) Shutdown(ctx context.Context) error {
	close(cm.watcher)

	var errs error
	errs = multierr.Append(errs, cm.closeIfNeeded(ctx))
	for _, p := range cm.configMapProviders {
		errs = multierr.Append(errs, p.Shutdown(ctx))
	}

	return errs
}

// follows drive-letter specification:
// https://tools.ietf.org/id/draft-kerwin-file-scheme-07.html#syntax
var driverLetterRegexp = regexp.MustCompile("^[A-z]:")

func (cm *configProvider) mergeRetrieve(ctx context.Context) (*configmapprovider.Retrieved, error) {
	var closers []configmapprovider.CloseFunc
	retCfgMap := config.NewMap()
	for _, location := range cm.locations {
		// For backwards compatibility:
		// - empty url scheme means "file".
		// - "^[A-z]:" also means "file"
		scheme := "file"
		if idx := strings.Index(location, ":"); idx != -1 && !driverLetterRegexp.MatchString(location) {
			scheme = location[:idx]
		} else {
			location = scheme + ":" + location
		}
		p, ok := cm.configMapProviders[scheme]
		if !ok {
			return nil, fmt.Errorf("scheme %v is not supported for location %v", scheme, location)
		}
		retr, err := p.Retrieve(ctx, location, cm.onChange)
		if err != nil {
			return nil, err
		}
		if err = retCfgMap.Merge(retr.Map); err != nil {
			return nil, err
		}
		if retr.CloseFunc != nil {
			closers = append(closers, retr.CloseFunc)
		}
	}
	return &configmapprovider.Retrieved{
		Map: retCfgMap,
		CloseFunc: func(ctxF context.Context) error {
			var err error
			for _, ret := range closers {
				err = multierr.Append(err, ret(ctxF))
			}
			return err
		},
	}, nil
}
<commit_msg>Update comment line for service.MustNewDefaultConfigProvider (#4964)<commit_after>// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package service // import "go.opentelemetry.io/collector/service"

import (
	"context"
	"fmt"
	"regexp"
	"strings"
	"sync"

	"go.uber.org/multierr"

	"go.opentelemetry.io/collector/component"
	"go.opentelemetry.io/collector/config"
	"go.opentelemetry.io/collector/config/configmapprovider"
	"go.opentelemetry.io/collector/config/configunmarshaler"
	"go.opentelemetry.io/collector/config/experimental/configsource"
)

// ConfigProvider provides the service configuration.
//
// The typical usage is the following:
//
//		cfgProvider.Get(...)
//		cfgProvider.Watch() // wait for an event.
//		cfgProvider.Get(...)
//		cfgProvider.Watch() // wait for an event.
//		// repeat Get/Watch cycle until it is time to shut down the Collector process.
//		cfgProvider.Shutdown()
type ConfigProvider interface {
	// Get returns the service configuration, or error otherwise.
	//
	// Should never be called concurrently with itself, Watch or Shutdown.
	Get(ctx context.Context, factories component.Factories) (*config.Config, error)

	// Watch blocks until any configuration change was detected or an unrecoverable error
	// happened during monitoring the configuration changes.
	//
	// Error is nil if the configuration is changed and needs to be re-fetched. Any non-nil
	// error indicates that there was a problem with watching the config changes.
	//
	// Should never be called concurrently with itself or Get.
	Watch() <-chan error

	// Shutdown signals that the provider is no longer in use and the that should close
	// and release any resources that it may have created.
	//
	// This function must terminate the Watch channel.
	//
	// Should never be called concurrently with itself or Get.
	Shutdown(ctx context.Context) error
}

type configProvider struct {
	locations          []string
	configMapProviders map[string]configmapprovider.Provider
	cfgMapConverters   []config.MapConverterFunc
	configUnmarshaler  configunmarshaler.ConfigUnmarshaler

	sync.Mutex
	closer  configmapprovider.CloseFunc
	watcher chan error
}

// MustNewConfigProvider returns a new ConfigProvider that provides the configuration:
// * Retrieve the config.Map by merging all retrieved maps from all the configmapprovider.Provider in order.
// * Then applies all the ConfigMapConverterFunc in the given order.
// * Then unmarshalls the final config.Config using the given configunmarshaler.ConfigUnmarshaler.
//
// The `configMapProviders` is a map of pairs <scheme,Provider>.
func MustNewConfigProvider(
	locations []string,
	configMapProviders map[string]configmapprovider.Provider,
	cfgMapConverters []config.MapConverterFunc,
	configUnmarshaler configunmarshaler.ConfigUnmarshaler) ConfigProvider {
	// Safe copy, ensures the slice cannot be changed from the caller.
	locationsCopy := make([]string, len(locations))
	copy(locationsCopy, locations)
	return &configProvider{
		locations:          locationsCopy,
		configMapProviders: configMapProviders,
		cfgMapConverters:   cfgMapConverters,
		configUnmarshaler:  configUnmarshaler,
		watcher:            make(chan error, 1),
	}
}

// MustNewDefaultConfigProvider returns the default ConfigProvider from slice of location strings
// (e.g. file:/path/to/config.yaml) and property overrides (e.g. service.telemetry.metrics.address=localhost:8888).
func MustNewDefaultConfigProvider(configLocations []string, properties []string) ConfigProvider {
	return MustNewConfigProvider(
		configLocations,
		map[string]configmapprovider.Provider{
			"file": configmapprovider.NewFile(),
			"env":  configmapprovider.NewEnv(),
		},
		[]config.MapConverterFunc{
			configmapprovider.NewOverwritePropertiesConverter(properties),
			configmapprovider.NewExpandConverter(),
		},
		configunmarshaler.NewDefault())
}

func (cm *configProvider) Get(ctx context.Context, factories component.Factories) (*config.Config, error) {
	// First check if already an active watching, close that if any.
	if err := cm.closeIfNeeded(ctx); err != nil {
		return nil, fmt.Errorf("cannot close previous watch: %w", err)
	}

	ret, err := cm.mergeRetrieve(ctx)
	if err != nil {
		return nil, fmt.Errorf("cannot retrieve the configuration: %w", err)
	}
	cm.closer = ret.CloseFunc

	// Apply all converters.
	for _, cfgMapConv := range cm.cfgMapConverters {
		if err = cfgMapConv(ctx, ret.Map); err != nil {
			return nil, fmt.Errorf("cannot convert the config.Map: %w", err)
		}
	}

	var cfg *config.Config
	if cfg, err = cm.configUnmarshaler.Unmarshal(ret.Map, factories); err != nil {
		return nil, fmt.Errorf("cannot unmarshal the configuration: %w", err)
	}

	if err = cfg.Validate(); err != nil {
		return nil, fmt.Errorf("invalid configuration: %w", err)
	}

	return cfg, nil
}

func (cm *configProvider) Watch() <-chan error {
	return cm.watcher
}

func (cm *configProvider) onChange(event *configmapprovider.ChangeEvent) {
	// TODO: Remove check for configsource.ErrSessionClosed when providers updated to not call onChange when closed.
	if event.Error != configsource.ErrSessionClosed {
		cm.watcher <- event.Error
	}
}

func (cm *configProvider) closeIfNeeded(ctx context.Context) error {
	if cm.closer != nil {
		return cm.closer(ctx)
	}
	return nil
}

func (cm *configProvider) Shutdown(ctx context.Context) error {
	close(cm.watcher)

	var errs error
	errs = multierr.Append(errs, cm.closeIfNeeded(ctx))
	for _, p := range cm.configMapProviders {
		errs = multierr.Append(errs, p.Shutdown(ctx))
	}

	return errs
}

// follows drive-letter specification:
// https://tools.ietf.org/id/draft-kerwin-file-scheme-07.html#syntax
var driverLetterRegexp = regexp.MustCompile("^[A-z]:")

func (cm *configProvider) mergeRetrieve(ctx context.Context) (*configmapprovider.Retrieved, error) {
	var closers []configmapprovider.CloseFunc
	retCfgMap := config.NewMap()
	for _, location := range cm.locations {
		// For backwards compatibility:
		// - empty url scheme means "file".
		// - "^[A-z]:" also means "file"
		scheme := "file"
		if idx := strings.Index(location, ":"); idx != -1 && !driverLetterRegexp.MatchString(location) {
			scheme = location[:idx]
		} else {
			location = scheme + ":" + location
		}
		p, ok := cm.configMapProviders[scheme]
		if !ok {
			return nil, fmt.Errorf("scheme %v is not supported for location %v", scheme, location)
		}
		retr, err := p.Retrieve(ctx, location, cm.onChange)
		if err != nil {
			return nil, err
		}
		if err = retCfgMap.Merge(retr.Map); err != nil {
			return nil, err
		}
		if retr.CloseFunc != nil {
			closers = append(closers, retr.CloseFunc)
		}
	}
	return &configmapprovider.Retrieved{
		Map: retCfgMap,
		CloseFunc: func(ctxF context.Context) error {
			var err error
			for _, ret := range closers {
				err = multierr.Append(err, ret(ctxF))
			}
			return err
		},
	}, nil
}
<|endoftext|>


<commit_before>package userService

import (
	"github.com/ewhalnyaa/db"
	"github.com/ewhal/nyaa/model"
	//   "github.com/gin-gonic/gin"
	"errors"
	"net/http"

	"github.com/ewhal/nyaa/util/log"
	//   "github.com/dorajistyle/goyangi/util/crypto"
)

// FindUserByUserName creates a user.
func FindUserByUserName(appID int64, userName string) (model.User, int, error) {
	var user model.User
	var err error
	// token := c.Request.Header.Get("X-Auth-Token")
	if db.ORM.Where("app_id=? and name=?", appID, userName).First(&user).RecordNotFound() {
		return user, http.StatusUnauthorized, err
	}
	return user, http.StatusOK, nil
}

// FindOrCreateUser creates a user.
func FindOrCreateUser(appID int64, userName string) (model.User, int, error) {
	var user model.User
	var err error

	// if len(token) > 0 {
	// 	log.Debug("header token exist.")
	// } else {
	// 	token, err = Token(c)
	// 	log.Debug("header token not exist.")
	// 	if err != nil {
	// 		return user, http.StatusUnauthorized, err
	// 	}
	// }
	log.Debugf("userName : %s\n", userName)
	// log.Debugf("Error : %s\n", err.Error())
	if db.ORM.Where("app_id=? and name=?", appID, userName).First(&user).RecordNotFound() {
		var user model.User
		// return user, http.StatusBadRequest, err
		user.Name = userName
		// user.Token = token
		user.AppID = appID
		log.Debugf("user %+v\n", user)
		if db.ORM.Create(&user).Error != nil {
			return user, http.StatusBadRequest, errors.New("User is not created.")
		}
		log.Debugf("retrived User %v\n", user)
		return user, http.StatusOK, nil
	}
	return user, http.StatusBadRequest, nil
}
<commit_msg>Update userHelper.go<commit_after>package userService

import (
	"github.com/ewhal/nyaa/db"
	"github.com/ewhal/nyaa/model"
	//   "github.com/gin-gonic/gin"
	"errors"
	"net/http"

	"github.com/ewhal/nyaa/util/log"
	//   "github.com/dorajistyle/goyangi/util/crypto"
)

// FindUserByUserName creates a user.
func FindUserByUserName(appID int64, userName string) (model.User, int, error) {
	var user model.User
	var err error
	// token := c.Request.Header.Get("X-Auth-Token")
	if db.ORM.Where("app_id=? and name=?", appID, userName).First(&user).RecordNotFound() {
		return user, http.StatusUnauthorized, err
	}
	return user, http.StatusOK, nil
}

// FindOrCreateUser creates a user.
func FindOrCreateUser(appID int64, userName string) (model.User, int, error) {
	var user model.User
	var err error

	// if len(token) > 0 {
	// 	log.Debug("header token exist.")
	// } else {
	// 	token, err = Token(c)
	// 	log.Debug("header token not exist.")
	// 	if err != nil {
	// 		return user, http.StatusUnauthorized, err
	// 	}
	// }
	log.Debugf("userName : %s\n", userName)
	// log.Debugf("Error : %s\n", err.Error())
	if db.ORM.Where("app_id=? and name=?", appID, userName).First(&user).RecordNotFound() {
		var user model.User
		// return user, http.StatusBadRequest, err
		user.Name = userName
		// user.Token = token
		user.AppID = appID
		log.Debugf("user %+v\n", user)
		if db.ORM.Create(&user).Error != nil {
			return user, http.StatusBadRequest, errors.New("User is not created.")
		}
		log.Debugf("retrived User %v\n", user)
		return user, http.StatusOK, nil
	}
	return user, http.StatusBadRequest, nil
}
<|endoftext|>


<commit_before>package version

// Version of Functions
var Version = "0.3.347"
<commit_msg>fnserver: 0.3.348 release [skip ci]<commit_after>package version

// Version of Functions
var Version = "0.3.348"
<|endoftext|>


<commit_before>package version

// Version of Functions
var Version = "0.3.740"
<commit_msg>fnserver: v0.3.741 release [skip ci]<commit_after>package version

// Version of Functions
var Version = "0.3.741"
<|endoftext|>


<commit_before>package apitypes

import (
	"encoding/json"
	"errors"
	"reflect"
	"strconv"

	"github.com/arigatomachine/cli/identity"
	"github.com/arigatomachine/cli/pathexp"
)

var errMistmatchedType = errors.New("Mismatched type and value in credential")

const (
	unsetCV = iota
	stringCV
	intCV
	floatCV
)

// CredentialEnvelope is an unencrypted credential object with a
// deserialized body
type CredentialEnvelope struct {
	ID      *identity.ID `json:"id"`
	Version uint8        `json:"version"`
	Body    *Credential  `json:"body"`
}

// CredentialResp is used to facilitate unmarshalling of versioned objects
type CredentialResp struct {
	ID      *identity.ID    `json:"id"`
	Version uint8           `json:"version"`
	Body    json.RawMessage `json:"body"`
}

// Credential interface is either a v1 or v2 credential object
type Credential interface {
	GetName() string
	GetOrgID() *identity.ID
	GetPathExp() *pathexp.PathExp
	GetProjectID() *identity.ID
	GetValue() *CredentialValue
}

// BaseCredential is the body of an unencrypted Credential
type BaseCredential struct {
	Name      string           `json:"name"`
	OrgID     *identity.ID     `json:"org_id"`
	PathExp   *pathexp.PathExp `json:"pathexp"`
	ProjectID *identity.ID     `json:"project_id"`
	Value     *CredentialValue `json:"value"`
}

// GetName returns the name
func (c *BaseCredential) GetName() string {
	return c.Name
}

// GetOrgID returns the org id
func (c *BaseCredential) GetOrgID() *identity.ID {
	return c.OrgID
}

// GetPathExp returns the pathexp
func (c *BaseCredential) GetPathExp() *pathexp.PathExp {
	return c.PathExp
}

// GetProjectID returns the project id
func (c *BaseCredential) GetProjectID() *identity.ID {
	return c.ProjectID
}

// GetValue returns the value object, unless unset then returns nil
func (c *BaseCredential) GetValue() *CredentialValue {
	if c.Value.cvtype == unsetCV {
		return nil
	}
	return c.Value
}

// CredentialV2 is the body of an unencrypted Credential
type CredentialV2 struct {
	BaseCredential
	State string `json:"state"`
}

// GetValue returns the value object, unless unset then returns nil
func (c *CredentialV2) GetValue() *CredentialValue {
	if c.Value == nil {
		return nil
	}
	if c.State == "unset" {
		return nil
	}
	return c.Value
}

// CredentialValue is the raw value of a credential.
type CredentialValue struct {
	cvtype int
	value  string
	raw    interface{}
}

// IsUnset returns if this credential has been unset (deleted)
func (c *CredentialValue) IsUnset() bool {
	return c.cvtype == unsetCV
}

// String returns the string representation of this credential. It panics
// if the credential was deleted.
func (c *CredentialValue) String() string {
	if c.cvtype == unsetCV {
		panic("CredentialValue has been unset")
	}

	return c.value
}

type credentialImpl struct {
	Version uint8 `json:"version"`
	Body    struct {
		Type  string          `json:"type"`
		Value json.RawMessage `json:"value"`
	} `json:"body"`
}

// MarshalJSON implements the json.Marshaler interface.
func (c *CredentialValue) MarshalJSON() ([]byte, error) {
	impl := credentialImpl{Version: 1}

	switch c.cvtype {
	case stringCV:
		impl.Body.Type = "string"
	case intCV:
		impl.Body.Type = "number"
	case floatCV:
		impl.Body.Type = "number"
	case unsetCV:
		impl.Body.Type = "undefined"
	}

	if c.cvtype != unsetCV {
		v, err := json.Marshal(c.raw)
		if err != nil {
			return nil, err
		}

		impl.Body.Value = v
	} else {
		impl.Body.Value = []byte(`""`)
	}

	b, err := json.Marshal(&impl)
	if err != nil {
		return nil, err
	}

	return []byte(strconv.Quote(string(b))), nil
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (c *CredentialValue) UnmarshalJSON(b []byte) error {
	impl := credentialImpl{}

	s, err := strconv.Unquote(string(b))
	if err != nil {
		return err
	}

	if len(s) == 0 {
		v := reflect.ValueOf(c).Elem()
		v.Set(reflect.Zero(v.Type()))
		return nil
	}

	err = json.Unmarshal([]byte(s), &impl)
	if err != nil {
		return err
	}

	switch impl.Body.Type {
	case "undefined":
		c.cvtype = unsetCV
	case "string":
		c.cvtype = stringCV
		var v string
		err := json.Unmarshal(impl.Body.Value, &v)
		if err != nil {
			return errMistmatchedType
		}

		c.raw = v
		c.value = v
	case "number":
		c.cvtype = stringCV
		var v json.Number
		err := json.Unmarshal(impl.Body.Value, &v)
		if err != nil {
			return errMistmatchedType
		}

		if i, err := v.Int64(); err == nil {
			c.cvtype = intCV
			c.raw = i
		} else if f, err := v.Float64(); err == nil {
			c.cvtype = floatCV
			c.raw = f
		}

		c.value = v.String()
	default:
		return errors.New("Decoding type " + impl.Body.Type + " is not supported")
	}
	return nil
}

// NewUnsetCredentialValue creates a CredentialValue with an unset value.
func NewUnsetCredentialValue() *CredentialValue {
	return &CredentialValue{cvtype: unsetCV}
}

// NewStringCredentialValue creates a CredentialValue with a string value.
func NewStringCredentialValue(s string) *CredentialValue {
	return &CredentialValue{
		cvtype: stringCV,
		value:  s,
		raw:    s,
	}
}

// NewIntCredentialValue creates a CredentialValue with an int value.
func NewIntCredentialValue(i int) *CredentialValue {
	return &CredentialValue{
		cvtype: intCV,
		value:  strconv.Itoa(i),
		raw:    i,
	}
}

// NewFloatCredentialValue creates a CredentialValue with a float value.
func NewFloatCredentialValue(f float64) *CredentialValue {
	return &CredentialValue{
		cvtype: floatCV,
		value:  strconv.FormatFloat(f, 'g', -1, 64),
		raw:    f,
	}
}
<commit_msg>Prevent unset credentialvalue from being included in credential set<commit_after>package apitypes

import (
	"encoding/json"
	"errors"
	"reflect"
	"strconv"

	"github.com/arigatomachine/cli/identity"
	"github.com/arigatomachine/cli/pathexp"
)

var errMistmatchedType = errors.New("Mismatched type and value in credential")

const (
	unsetCV = iota
	stringCV
	intCV
	floatCV
)

// CredentialEnvelope is an unencrypted credential object with a
// deserialized body
type CredentialEnvelope struct {
	ID      *identity.ID `json:"id"`
	Version uint8        `json:"version"`
	Body    *Credential  `json:"body"`
}

// CredentialResp is used to facilitate unmarshalling of versioned objects
type CredentialResp struct {
	ID      *identity.ID    `json:"id"`
	Version uint8           `json:"version"`
	Body    json.RawMessage `json:"body"`
}

// Credential interface is either a v1 or v2 credential object
type Credential interface {
	GetName() string
	GetOrgID() *identity.ID
	GetPathExp() *pathexp.PathExp
	GetProjectID() *identity.ID
	GetValue() *CredentialValue
}

// BaseCredential is the body of an unencrypted Credential
type BaseCredential struct {
	Name      string           `json:"name"`
	OrgID     *identity.ID     `json:"org_id"`
	PathExp   *pathexp.PathExp `json:"pathexp"`
	ProjectID *identity.ID     `json:"project_id"`
	Value     *CredentialValue `json:"value"`
}

// GetName returns the name
func (c *BaseCredential) GetName() string {
	return c.Name
}

// GetOrgID returns the org id
func (c *BaseCredential) GetOrgID() *identity.ID {
	return c.OrgID
}

// GetPathExp returns the pathexp
func (c *BaseCredential) GetPathExp() *pathexp.PathExp {
	return c.PathExp
}

// GetProjectID returns the project id
func (c *BaseCredential) GetProjectID() *identity.ID {
	return c.ProjectID
}

// GetValue returns the value object, unless unset then returns nil
func (c *BaseCredential) GetValue() *CredentialValue {
	if c.Value.cvtype == unsetCV {
		return nil
	}
	return c.Value
}

// CredentialV2 is the body of an unencrypted Credential
type CredentialV2 struct {
	BaseCredential
	State string `json:"state"`
}

// GetValue returns the value object, unless unset then returns nil
func (c *CredentialV2) GetValue() *CredentialValue {
	if c.State == "unset" { // v2 unset state
		return nil
	}
	if c.Value == nil { // v2 value nilled
		return nil
	}
	if c.Value.IsUnset() { // value contains v1 undefined type
		return nil
	}
	return c.Value
}

// CredentialValue is the raw value of a credential.
type CredentialValue struct {
	cvtype int
	value  string
	raw    interface{}
}

// IsUnset returns if this credential has been unset (deleted)
func (c *CredentialValue) IsUnset() bool {
	return c.cvtype == unsetCV
}

// String returns the string representation of this credential. It panics
// if the credential was deleted.
func (c *CredentialValue) String() string {
	if c.cvtype == unsetCV {
		panic("CredentialValue has been unset")
	}

	return c.value
}

type credentialImpl struct {
	Version uint8 `json:"version"`
	Body    struct {
		Type  string          `json:"type"`
		Value json.RawMessage `json:"value"`
	} `json:"body"`
}

// MarshalJSON implements the json.Marshaler interface.
func (c *CredentialValue) MarshalJSON() ([]byte, error) {
	impl := credentialImpl{Version: 1}

	switch c.cvtype {
	case stringCV:
		impl.Body.Type = "string"
	case intCV:
		impl.Body.Type = "number"
	case floatCV:
		impl.Body.Type = "number"
	case unsetCV:
		impl.Body.Type = "undefined"
	}

	if c.cvtype != unsetCV {
		v, err := json.Marshal(c.raw)
		if err != nil {
			return nil, err
		}

		impl.Body.Value = v
	} else {
		impl.Body.Value = []byte(`""`)
	}

	b, err := json.Marshal(&impl)
	if err != nil {
		return nil, err
	}

	return []byte(strconv.Quote(string(b))), nil
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (c *CredentialValue) UnmarshalJSON(b []byte) error {
	impl := credentialImpl{}

	s, err := strconv.Unquote(string(b))
	if err != nil {
		return err
	}

	if len(s) == 0 {
		v := reflect.ValueOf(c).Elem()
		v.Set(reflect.Zero(v.Type()))
		return nil
	}

	err = json.Unmarshal([]byte(s), &impl)
	if err != nil {
		return err
	}

	switch impl.Body.Type {
	case "undefined":
		c.cvtype = unsetCV
	case "string":
		c.cvtype = stringCV
		var v string
		err := json.Unmarshal(impl.Body.Value, &v)
		if err != nil {
			return errMistmatchedType
		}

		c.raw = v
		c.value = v
	case "number":
		c.cvtype = stringCV
		var v json.Number
		err := json.Unmarshal(impl.Body.Value, &v)
		if err != nil {
			return errMistmatchedType
		}

		if i, err := v.Int64(); err == nil {
			c.cvtype = intCV
			c.raw = i
		} else if f, err := v.Float64(); err == nil {
			c.cvtype = floatCV
			c.raw = f
		}

		c.value = v.String()
	default:
		return errors.New("Decoding type " + impl.Body.Type + " is not supported")
	}
	return nil
}

// NewUnsetCredentialValue creates a CredentialValue with an unset value.
func NewUnsetCredentialValue() *CredentialValue {
	return &CredentialValue{cvtype: unsetCV}
}

// NewStringCredentialValue creates a CredentialValue with a string value.
func NewStringCredentialValue(s string) *CredentialValue {
	return &CredentialValue{
		cvtype: stringCV,
		value:  s,
		raw:    s,
	}
}

// NewIntCredentialValue creates a CredentialValue with an int value.
func NewIntCredentialValue(i int) *CredentialValue {
	return &CredentialValue{
		cvtype: intCV,
		value:  strconv.Itoa(i),
		raw:    i,
	}
}

// NewFloatCredentialValue creates a CredentialValue with a float value.
func NewFloatCredentialValue(f float64) *CredentialValue {
	return &CredentialValue{
		cvtype: floatCV,
		value:  strconv.FormatFloat(f, 'g', -1, 64),
		raw:    f,
	}
}
<|endoftext|>


<commit_before>// package method implements http method override
// using the X-HTTP-Method-Override http header.
package method

import (
	"errors"
	"net/http"
)

// Commonly used Http header used to override the method
const HeaderHTTPMethodOverride = "X-HTTP-Method-Override"

var httpMethods = []string{"PUT", "PATCH", "DELETE"}

// An invalid http method was given to OverrideRequestMethod()
var ErrInvalidOverrideMethod = errors.New("invalid override method")

func isValidOverrideMethod(method string) bool {
	for _, m := range httpMethods {
		if m == method {
			return true
		}
	}
	return false
}

// Override checks for the X-HTTP-Method-Override header
// and uses (if valid) the http method instead of
// Request.Method.
// This is especially useful for http clients
// that don't support many http verbs.
// It isn't secure to override e.g a GET to a POST,
// so only Request.Method which are POSTs are considered.
func Override() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "POST" {
			m := r.Header.Get(HeaderHTTPMethodOverride)
			if isValidOverrideMethod(m) {
				r.Method = m
			}
		}
	})
}

// Overrides the http request's method with the specified method
func OverrideRequestMethod(r *http.Request, method string) error {
	if !isValidOverrideMethod(method) {
		return ErrInvalidOverrideMethod
	}
	r.Header.Set(HeaderHTTPMethodOverride, method)
	return nil
}
<commit_msg>Reword and normalize godoc<commit_after>// package method implements http method override
// using the X-HTTP-Method-Override http header.
package method

import (
	"errors"
	"net/http"
)

// HeaderHTTPMethodOverride is a commonly used
// Http header to override the method.
const HeaderHTTPMethodOverride = "X-HTTP-Method-Override"

var httpMethods = []string{"PUT", "PATCH", "DELETE"}

// ErrInvalidOverrideMethod is returned when
// an invalid http method was given to OverrideRequestMethod.
var ErrInvalidOverrideMethod = errors.New("invalid override method")

func isValidOverrideMethod(method string) bool {
	for _, m := range httpMethods {
		if m == method {
			return true
		}
	}
	return false
}

// Override checks for the X-HTTP-Method-Override header
// and uses (if valid) the http method instead of
// Request.Method.
// This is especially useful for http clients
// that don't support many http verbs.
// It isn't secure to override e.g a GET to a POST,
// so only Request.Method which are POSTs are considered.
func Override() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "POST" {
			m := r.Header.Get(HeaderHTTPMethodOverride)
			if isValidOverrideMethod(m) {
				r.Method = m
			}
		}
	})
}

// OverrideRequestMethod overrides the http
// request's method with the specified method.
func OverrideRequestMethod(r *http.Request, method string) error {
	if !isValidOverrideMethod(method) {
		return ErrInvalidOverrideMethod
	}
	r.Header.Set(HeaderHTTPMethodOverride, method)
	return nil
}
<|endoftext|>


<commit_before>// +build acceptance

package app_test

import (
	"flag"
	"fmt"
	"os"
	"time"

	"github.com/DATA-DOG/godog"
)

var FeatureContext func(s *godog.Suite)

func init() {
	runners = append(runners, func() int {
		format := "progress"
		seed := int64(0)

		var verbose, randomize bool
		flags := flag.NewFlagSet(os.Args[0], flag.ExitOnError)

		// go test transforms -v option
		flags.BoolVar(&verbose, "test.v", false, "Test verbosity")
		flags.BoolVar(&randomize, "randomize", false, "Randomize acceptance test order")
		flags.Parse(os.Args[1:])

		if verbose {
			format = "pretty"
		}

		// Randomize scenario execution order
		if randomize {
			seed = time.Now().UTC().UnixNano()
		}

		featureContext := FeatureContext
		if featureContext == nil {
			featureContext = func(s *godog.Suite) {
				fmt.Println("No feature context")
			}
		}

		return godog.RunWithOptions(
			"godog",
			featureContext,
			godog.Options{
				Format:    format,
				Paths:     []string{"../features"},
				Randomize: seed,
			},
		)
	})
}
<commit_msg>Use environment variable instead of test flag<commit_after>// +build acceptance

package app_test

import (
	"flag"
	"fmt"
	"os"
	"strconv"
	"time"

	"github.com/DATA-DOG/godog"
)

var FeatureContext func(s *godog.Suite)

func init() {
	runners = append(runners, func() int {
		format := "progress"
		seed := int64(0)

		// go test transforms -v option
		if verbose := flag.Lookup("test.v"); verbose != nil {
			format = "pretty"
		}

		// Randomize scenario execution order
		if randomize, _ := strconv.ParseBool(os.Getenv("TEST_RANDOMIZE")); randomize {
			seed = time.Now().UTC().UnixNano()
		}

		featureContext := FeatureContext
		if featureContext == nil {
			featureContext = func(s *godog.Suite) {
				fmt.Println("No feature context")
			}
		}

		return godog.RunWithOptions(
			"godog",
			featureContext,
			godog.Options{
				Format:    format,
				Paths:     []string{"../features"},
				Randomize: seed,
			},
		)
	})
}
<|endoftext|>