<commit_before>package main

import (
	"log"
	"net"
	"net/http"
	"strconv"

	"github.com/robustirc/robustirc/ircserver"
	"github.com/robustirc/robustirc/types"

	"github.com/hashicorp/raft"
)

//go:generate go run gentmpl.go status irclog

func handleStatus(res http.ResponseWriter, req *http.Request) {
	p, _ := peerStore.Peers()

	lo, err := ircStore.FirstIndex()
	if err != nil {
		log.Printf("Could not get first index: %v", err)
		http.Error(res, "internal error", 500)
		return
	}
	hi, err := ircStore.LastIndex()
	if err != nil {
		log.Printf("Could not get last index: %v", err)
		http.Error(res, "internal error", 500)
		return
	}

	// Show the last 50 messages by default.
	if hi > 50 && hi-50 > lo {
		lo = hi - 50
	}

	if offsetStr := req.FormValue("offset"); offsetStr != "" {
		offset, err := strconv.ParseInt(offsetStr, 0, 64)
		if err != nil {
			http.Error(res, err.Error(), http.StatusBadRequest)
			return
		}
		lo = uint64(offset)
	}

	if hi > lo+50 {
		hi = lo + 50
	}

	var entries []*raft.Log
	if lo != 0 && hi != 0 {
		for i := lo; i <= hi; i++ {
			l := new(raft.Log)

			if err := ircStore.GetLog(i, l); err != nil {
				// Not every message goes into the ircStore (e.g. raft peer change
				// messages do not).
				continue
			}
			entries = append(entries, l)
		}
	}

	prevOffset := int64(lo) - 50
	if prevOffset < 0 {
		prevOffset = 1
	}

	args := struct {
		Addr               string
		State              raft.RaftState
		Leader             net.Addr
		Peers              []net.Addr
		First              uint64
		Last               uint64
		Entries            []*raft.Log
		Stats              map[string]string
		Sessions           map[types.RobustId]ircserver.Session
		GetMessageRequests map[string]GetMessageStats
		PrevOffset         int64
		NextOffset         uint64
	}{
		*peerAddr,
		node.State(),
		node.Leader(),
		p,
		lo,
		hi,
		entries,
		node.Stats(),
		ircServer.GetSessions(),
		GetMessageRequests,
		prevOffset,
		lo + 50,
	}

	statusTpl.Execute(res, args)
}

func handleIrclog(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.ParseInt(r.FormValue("sessionid"), 0, 64)
	if err != nil || id == 0 {
		http.Error(w, "Invalid session", http.StatusBadRequest)
		return
	}

	session := types.RobustId{Id: id}

	// TODO(secure): pagination

	var messages []*types.RobustMessage
	first, _ := ircStore.FirstIndex()
	last, _ := ircStore.LastIndex()
	for idx := first; idx <= last; idx++ {
		var elog raft.Log

		if err := ircStore.GetLog(idx, &elog); err != nil {
			// Not every message goes into the ircStore (e.g. raft peer change
			// messages do not).
			continue
		}
		if elog.Type != raft.LogCommand {
			continue
		}
		msg := types.NewRobustMessageFromBytes(elog.Data)
		if msg.Session.Id != session.Id {
			continue
		}
		messages = append(messages, &msg)
		output, ok := ircServer.Get(msg.Id)
		if ok {
			messages = append(messages, output...)
		}
	}

	args := struct {
		Session  types.RobustId
		Messages []*types.RobustMessage
	}{
		session,
		messages,
	}
	if err := irclogTpl.Execute(w, args); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}
<commit_msg>Make status available as JSON.<commit_after>package main

import (
	"encoding/json"
	"log"
	"net"
	"net/http"
	"strconv"

	"github.com/robustirc/robustirc/ircserver"
	"github.com/robustirc/robustirc/types"

	"github.com/hashicorp/raft"
)

//go:generate go run gentmpl.go status irclog

func handleStatus(res http.ResponseWriter, req *http.Request) {
	p, _ := peerStore.Peers()

	// robustirc-rollingrestart wants a machine-readable version of the status.
	if req.Header.Get("Accept") == "application/json" {
		type jsonStatus struct {
			State        string
			Leader       string
			Peers        []net.Addr
			AppliedIndex uint64
			CommitIndex  uint64
		}
		res.Header().Set("Content-Type", "application/json")
		leaderStr := ""
		leader := node.Leader()
		if leader != nil {
			leaderStr = leader.String()
		}
		stats := node.Stats()
		appliedIndex, err := strconv.ParseUint(stats["applied_index"], 0, 64)
		if err != nil {
			http.Error(res, err.Error(), http.StatusInternalServerError)
			return
		}
		commitIndex, err := strconv.ParseUint(stats["commit_index"], 0, 64)
		if err != nil {
			http.Error(res, err.Error(), http.StatusInternalServerError)
			return
		}
		if err := json.NewEncoder(res).Encode(jsonStatus{
			State:        node.State().String(),
			Leader:       leaderStr,
			AppliedIndex: appliedIndex,
			CommitIndex:  commitIndex,
			Peers:        p,
		}); err != nil {
			log.Printf("%v\n", err)
			http.Error(res, err.Error(), http.StatusInternalServerError)
		}
		return
	}

	lo, err := ircStore.FirstIndex()
	if err != nil {
		log.Printf("Could not get first index: %v", err)
		http.Error(res, "internal error", 500)
		return
	}
	hi, err := ircStore.LastIndex()
	if err != nil {
		log.Printf("Could not get last index: %v", err)
		http.Error(res, "internal error", 500)
		return
	}

	// Show the last 50 messages by default.
	if hi > 50 && hi-50 > lo {
		lo = hi - 50
	}

	if offsetStr := req.FormValue("offset"); offsetStr != "" {
		offset, err := strconv.ParseInt(offsetStr, 0, 64)
		if err != nil {
			http.Error(res, err.Error(), http.StatusBadRequest)
			return
		}
		lo = uint64(offset)
	}

	if hi > lo+50 {
		hi = lo + 50
	}

	var entries []*raft.Log
	if lo != 0 && hi != 0 {
		for i := lo; i <= hi; i++ {
			l := new(raft.Log)

			if err := ircStore.GetLog(i, l); err != nil {
				// Not every message goes into the ircStore (e.g. raft peer change
				// messages do not).
				continue
			}
			entries = append(entries, l)
		}
	}

	prevOffset := int64(lo) - 50
	if prevOffset < 0 {
		prevOffset = 1
	}

	args := struct {
		Addr               string
		State              raft.RaftState
		Leader             net.Addr
		Peers              []net.Addr
		First              uint64
		Last               uint64
		Entries            []*raft.Log
		Stats              map[string]string
		Sessions           map[types.RobustId]ircserver.Session
		GetMessageRequests map[string]GetMessageStats
		PrevOffset         int64
		NextOffset         uint64
	}{
		*peerAddr,
		node.State(),
		node.Leader(),
		p,
		lo,
		hi,
		entries,
		node.Stats(),
		ircServer.GetSessions(),
		GetMessageRequests,
		prevOffset,
		lo + 50,
	}

	statusTpl.Execute(res, args)
}

func handleIrclog(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.ParseInt(r.FormValue("sessionid"), 0, 64)
	if err != nil || id == 0 {
		http.Error(w, "Invalid session", http.StatusBadRequest)
		return
	}

	session := types.RobustId{Id: id}

	// TODO(secure): pagination

	var messages []*types.RobustMessage
	first, _ := ircStore.FirstIndex()
	last, _ := ircStore.LastIndex()
	for idx := first; idx <= last; idx++ {
		var elog raft.Log

		if err := ircStore.GetLog(idx, &elog); err != nil {
			// Not every message goes into the ircStore (e.g. raft peer change
			// messages do not).
			continue
		}
		if elog.Type != raft.LogCommand {
			continue
		}
		msg := types.NewRobustMessageFromBytes(elog.Data)
		if msg.Session.Id != session.Id {
			continue
		}
		messages = append(messages, &msg)
		output, ok := ircServer.Get(msg.Id)
		if ok {
			messages = append(messages, output...)
		}
	}

	args := struct {
		Session  types.RobustId
		Messages []*types.RobustMessage
	}{
		session,
		messages,
	}
	if err := irclogTpl.Execute(w, args); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}
<|endoftext|>


<commit_before>package dotweb

import (
	"github.com/devfeel/dotweb/framework/file"
	"html/template"
	"io"
	"path"
	"sync"
	"fmt"
)

// Renderer is the interface that wraps the render method.
type Renderer interface {
	SetTemplatePath(path string)
	Render(io.Writer, interface{}, Context, ...string) error
}

type innerRenderer struct {
	templatePath string
	// Template cache (for FromCache())
	enabledCache 	   bool
	templateCache      map[string]*template.Template
	templateCacheMutex sync.RWMutex
}

// Render render view use http/template
func (r *innerRenderer) Render(w io.Writer, data interface{}, ctx Context, tpl ...string) error {
	t, err := r.parseFiles(tpl...)
	if err != nil {
		return err
	}
	return t.Execute(w, data)
}

// SetTemplatePath set default template path
func (r *innerRenderer) SetTemplatePath(path string) {
	r.templatePath = path
}

// 定义函数unescaped
func unescaped(x string) interface{} { return template.HTML(x) }

// return http/template by gived file name
func (r *innerRenderer) parseFiles(fileNames ...string) (*template.Template, error) {
	var realFileNames []string
	var filesCacheKey string
	var err error
	for _, v := range fileNames {
		if !file.Exist(v) {
			v = path.Join(r.templatePath, v)
		}
		realFileNames = append(realFileNames, v)
		filesCacheKey = filesCacheKey + v
	}

	var t *template.Template
	var exists bool
	if r.enabledCache {
		//check from chach
		t, exists = r.parseFilesFromCache(filesCacheKey)
	}
	fmt.Println("parseFiles", r.enabledCache, filesCacheKey, t, exists)
	if !exists{
		t, err = template.ParseFiles(realFileNames...)
		if err != nil {
			return nil, err
		}
		r.templateCacheMutex.Lock()
		defer r.templateCacheMutex.Unlock()
		r.templateCache[filesCacheKey] = t
	}

	t = registeTemplateFunc(t)
	return t, nil
}

func (r *innerRenderer) parseFilesFromCache(filesCacheKey string) (*template.Template, bool){
	r.templateCacheMutex.RLock()
	defer r.templateCacheMutex.RUnlock()
	t, exists:= r.templateCache[filesCacheKey]
	return t, exists
}

// registeTemplateFunc registe default support funcs
func registeTemplateFunc(t *template.Template) *template.Template {
	return t.Funcs(template.FuncMap{"unescaped": unescaped})
	//TODO:add more func
}

// NewInnerRenderer create a inner renderer instance
func NewInnerRenderer() *innerRenderer {
	r := new(innerRenderer)
	r.enabledCache = true
	r.templateCache = make(map[string]*template.Template)
	return r
}

// NewInnerRenderer create a inner renderer instance
func NewInnerRendererNoCache() *innerRenderer {
	r := new(innerRenderer)
	r.enabledCache = false
	r.templateCache = make(map[string]*template.Template)
	return r
}

<commit_msg>#### Version 1.5.2 * New feature: dotweb.innerRenderer add cache mode, default is enabled * New feature: dotweb.innerRenderer add NewInnerRendererNoCache() used to disabled cache * Update for app run_mode: if it's develop run mode, the default renderer will use no cache mode * 2018-06-22 14:00<commit_after>package dotweb

import (
	"github.com/devfeel/dotweb/framework/file"
	"html/template"
	"io"
	"path"
	"sync"
)

// Renderer is the interface that wraps the render method.
type Renderer interface {
	SetTemplatePath(path string)
	Render(io.Writer, interface{}, Context, ...string) error
}

type innerRenderer struct {
	templatePath string
	// Template cache (for FromCache())
	enabledCache 	   bool
	templateCache      map[string]*template.Template
	templateCacheMutex sync.RWMutex
}

// Render render view use http/template
func (r *innerRenderer) Render(w io.Writer, data interface{}, ctx Context, tpl ...string) error {
	t, err := r.parseFiles(tpl...)
	if err != nil {
		return err
	}
	return t.Execute(w, data)
}

// SetTemplatePath set default template path
func (r *innerRenderer) SetTemplatePath(path string) {
	r.templatePath = path
}

// 定义函数unescaped
func unescaped(x string) interface{} { return template.HTML(x) }

// return http/template by gived file name
func (r *innerRenderer) parseFiles(fileNames ...string) (*template.Template, error) {
	var realFileNames []string
	var filesCacheKey string
	var err error
	for _, v := range fileNames {
		if !file.Exist(v) {
			v = path.Join(r.templatePath, v)
		}
		realFileNames = append(realFileNames, v)
		filesCacheKey = filesCacheKey + v
	}

	var t *template.Template
	var exists bool
	if r.enabledCache {
		//check from chach
		t, exists = r.parseFilesFromCache(filesCacheKey)
	}
	if !exists{
		t, err = template.ParseFiles(realFileNames...)
		if err != nil {
			return nil, err
		}
		r.templateCacheMutex.Lock()
		defer r.templateCacheMutex.Unlock()
		r.templateCache[filesCacheKey] = t
	}

	t = registeTemplateFunc(t)
	return t, nil
}

func (r *innerRenderer) parseFilesFromCache(filesCacheKey string) (*template.Template, bool){
	r.templateCacheMutex.RLock()
	defer r.templateCacheMutex.RUnlock()
	t, exists:= r.templateCache[filesCacheKey]
	return t, exists
}

// registeTemplateFunc registe default support funcs
func registeTemplateFunc(t *template.Template) *template.Template {
	return t.Funcs(template.FuncMap{"unescaped": unescaped})
	//TODO:add more func
}

// NewInnerRenderer create a inner renderer instance
func NewInnerRenderer() *innerRenderer {
	r := new(innerRenderer)
	r.enabledCache = true
	r.templateCache = make(map[string]*template.Template)
	return r
}

// NewInnerRenderer create a inner renderer instance
func NewInnerRendererNoCache() *innerRenderer {
	r := new(innerRenderer)
	r.enabledCache = false
	r.templateCache = make(map[string]*template.Template)
	return r
}

<|endoftext|>


<commit_before>package main

import (
	"flag"
	"io"
	"log"
	"os"
	"os/signal"
	"sort"
	"strings"

	vegeta "github.com/tsenart/vegeta/lib"
)

func reportCmd() command {
	fs := flag.NewFlagSet("vegeta report", flag.ExitOnError)
	reporter := fs.String("reporter", "text", "Reporter [text, json, plot]")
	inputs := fs.String("inputs", "stdin", "Input files (comma separated)")
	output := fs.String("output", "stdout", "Output file")
	return command{fs, func(args []string) error {
		fs.Parse(args)
		return report(*reporter, *inputs, *output)
	}}
}

// report validates the report arguments, sets up the required resources
// and writes the report
func report(reporter, inputs, output string) error {
	rep, ok := reporters[reporter]
	if !ok {
		log.Println("Reporter provided is not supported. Using text")
		rep = vegeta.ReportText
	}

	files := strings.Split(inputs, ",")
	srcs := make([]io.Reader, len(files))
	for i, f := range files {
		in, err := file(f, false)
		if err != nil {
			return err
		}
		defer in.Close()
		srcs[i] = in
	}

	out, err := file(output, true)
	if err != nil {
		return err
	}
	defer out.Close()

	var results vegeta.Results
	res, errs := vegeta.Collect(srcs...)
	sig := make(chan os.Signal, 1)
	signal.Notify(sig, os.Interrupt)

outer:
	for {
		select {
		case _ = <-sig:
			break outer
		case r, ok := <-res:
			if !ok {
				break outer
			}
			results = append(results, r)
		case err := <-errs:
			return err
		}
	}

	sort.Sort(results)
	data, err := rep.Report(results)
	if err != nil {
		return err
	}
	_, err = out.Write(data)
	return err
}

var reporters = map[string]vegeta.Reporter{
	"text": vegeta.ReportText,
	"json": vegeta.ReportJSON,
	"plot": vegeta.ReportPlot,
}
<commit_msg>report: Check if errs chan closed<commit_after>package main

import (
	"flag"
	"io"
	"log"
	"os"
	"os/signal"
	"sort"
	"strings"

	vegeta "github.com/tsenart/vegeta/lib"
)

func reportCmd() command {
	fs := flag.NewFlagSet("vegeta report", flag.ExitOnError)
	reporter := fs.String("reporter", "text", "Reporter [text, json, plot]")
	inputs := fs.String("inputs", "stdin", "Input files (comma separated)")
	output := fs.String("output", "stdout", "Output file")
	return command{fs, func(args []string) error {
		fs.Parse(args)
		return report(*reporter, *inputs, *output)
	}}
}

// report validates the report arguments, sets up the required resources
// and writes the report
func report(reporter, inputs, output string) error {
	rep, ok := reporters[reporter]
	if !ok {
		log.Println("Reporter provided is not supported. Using text")
		rep = vegeta.ReportText
	}

	files := strings.Split(inputs, ",")
	srcs := make([]io.Reader, len(files))
	for i, f := range files {
		in, err := file(f, false)
		if err != nil {
			return err
		}
		defer in.Close()
		srcs[i] = in
	}

	out, err := file(output, true)
	if err != nil {
		return err
	}
	defer out.Close()

	var results vegeta.Results
	res, errs := vegeta.Collect(srcs...)
	sig := make(chan os.Signal, 1)
	signal.Notify(sig, os.Interrupt)

outer:
	for {
		select {
		case _ = <-sig:
			break outer
		case r, ok := <-res:
			if !ok {
				break outer
			}
			results = append(results, r)
		case err, ok := <-errs:
			if !ok {
				break outer
			}
			return err
		}
	}

	sort.Sort(results)
	data, err := rep.Report(results)
	if err != nil {
		return err
	}
	_, err = out.Write(data)
	return err
}

var reporters = map[string]vegeta.Reporter{
	"text": vegeta.ReportText,
	"json": vegeta.ReportJSON,
	"plot": vegeta.ReportPlot,
}
<|endoftext|>


<commit_before>// Copyright 2015 Daniel Pupius

package dbps

import (
	"bytes"
	"image"
	"image/jpeg"

	_ "image/gif"
	_ "image/png"

	"github.com/dpup/dbps/internal/resize"
)

var nilBytes = []byte{}

func Resize(data []byte) ([]byte, error) {
	img, _, err := image.Decode(bytes.NewReader(data))
	if err != nil {
		return nilBytes, err
	}

	r := resize.Thumbnail(200, 200, img, resize.Bicubic)

	var b bytes.Buffer
	err = jpeg.Encode(&b, r, &jpeg.Options{95})
	if err != nil {
		return nilBytes, err
	}

	return b.Bytes(), nil
}
<commit_msg>Use square thumbnails<commit_after>// Copyright 2015 Daniel Pupius

package dbps

import (
	"bytes"
	"image"
	"image/jpeg"
	"math"

	_ "image/gif"
	_ "image/png"

	"github.com/dpup/dbps/internal/resize"
)

var nilBytes = []byte{}

func Resize(data []byte) ([]byte, error) {
	img, _, err := image.Decode(bytes.NewReader(data))
	if err != nil {
		return nilBytes, err
	}

	b := img.Bounds()
	s := math.Min(float64(b.Dx()), float64(b.Dy()))
	x := int(float64(b.Dx())/2 - s/2)
	y := int(float64(b.Dy())/2 - s/2)

	subImg := img.(interface {
		SubImage(r image.Rectangle) image.Image
	})

	squareImg := subImg.SubImage(image.Rect(x, y, x+int(s), y+int(s)))
	resizedImg := resize.Thumbnail(200, 200, squareImg, resize.Bicubic)

	var buf bytes.Buffer
	err = jpeg.Encode(&buf, resizedImg, &jpeg.Options{95})
	if err != nil {
		return nilBytes, err
	}

	return buf.Bytes(), nil
}
<|endoftext|>


<commit_before>package wrapper

import (
	"context"
	"reflect"
	"strings"

	"github.com/micro/go-micro/v2/auth"
	"github.com/micro/go-micro/v2/client"
	"github.com/micro/go-micro/v2/debug/stats"
	"github.com/micro/go-micro/v2/debug/trace"
	"github.com/micro/go-micro/v2/errors"
	"github.com/micro/go-micro/v2/metadata"
	"github.com/micro/go-micro/v2/server"
)

type fromServiceWrapper struct {
	client.Client

	// headers to inject
	headers metadata.Metadata
}

var (
	HeaderPrefix = "Micro-"
)

func (f *fromServiceWrapper) setHeaders(ctx context.Context) context.Context {
	// don't overwrite keys
	return metadata.MergeContext(ctx, f.headers, false)
}

func (f *fromServiceWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	ctx = f.setHeaders(ctx)
	return f.Client.Call(ctx, req, rsp, opts...)
}

func (f *fromServiceWrapper) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) {
	ctx = f.setHeaders(ctx)
	return f.Client.Stream(ctx, req, opts...)
}

func (f *fromServiceWrapper) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) error {
	ctx = f.setHeaders(ctx)
	return f.Client.Publish(ctx, p, opts...)
}

// FromService wraps a client to inject service and auth metadata
func FromService(name string, c client.Client) client.Client {
	return &fromServiceWrapper{
		c,
		metadata.Metadata{
			HeaderPrefix + "From-Service": name,
		},
	}
}

// HandlerStats wraps a server handler to generate request/error stats
func HandlerStats(stats stats.Stats) server.HandlerWrapper {
	// return a handler wrapper
	return func(h server.HandlerFunc) server.HandlerFunc {
		// return a function that returns a function
		return func(ctx context.Context, req server.Request, rsp interface{}) error {
			// execute the handler
			err := h(ctx, req, rsp)
			// record the stats
			stats.Record(err)
			// return the error
			return err
		}
	}
}

type traceWrapper struct {
	client.Client

	name  string
	trace trace.Tracer
}

func (c *traceWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	newCtx, s := c.trace.Start(ctx, req.Service()+"."+req.Endpoint())

	s.Type = trace.SpanTypeRequestOutbound
	err := c.Client.Call(newCtx, req, rsp, opts...)
	if err != nil {
		s.Metadata["error"] = err.Error()
	}

	// finish the trace
	c.trace.Finish(s)

	return err
}

// TraceCall is a call tracing wrapper
func TraceCall(name string, t trace.Tracer, c client.Client) client.Client {
	return &traceWrapper{
		name:   name,
		trace:  t,
		Client: c,
	}
}

// TraceHandler wraps a server handler to perform tracing
func TraceHandler(t trace.Tracer) server.HandlerWrapper {
	// return a handler wrapper
	return func(h server.HandlerFunc) server.HandlerFunc {
		// return a function that returns a function
		return func(ctx context.Context, req server.Request, rsp interface{}) error {
			// don't store traces for debug
			if strings.HasPrefix(req.Endpoint(), "Debug.") {
				return h(ctx, req, rsp)
			}

			// get the span
			newCtx, s := t.Start(ctx, req.Service()+"."+req.Endpoint())
			s.Type = trace.SpanTypeRequestInbound

			err := h(newCtx, req, rsp)
			if err != nil {
				s.Metadata["error"] = err.Error()
			}

			// finish
			t.Finish(s)

			return err
		}
	}
}

type authWrapper struct {
	client.Client
	auth func() auth.Auth
}

func (a *authWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	// parse the options
	var options client.CallOptions
	for _, o := range opts {
		o(&options)
	}

	// check to see if the authorization header has already been set.
	// We dont't override the header unless the ServiceToken option has
	// been specified or the header wasn't provided
	if _, ok := metadata.Get(ctx, "Authorization"); ok && !options.ServiceToken {
		return a.Client.Call(ctx, req, rsp, opts...)
	}

	// if auth is nil we won't be able to get an access token, so we execute
	// the request without one.
	aa := a.auth()
	if aa == nil {
		return a.Client.Call(ctx, req, rsp, opts...)
	}

	// set the namespace header if it has not been set (e.g. on a service to service request)
	if _, ok := metadata.Get(ctx, "Micro-Namespace"); !ok {
		ctx = metadata.Set(ctx, "Micro-Namespace", aa.Options().Namespace)
	}

	// check to see if we have a valid access token
	aaOpts := aa.Options()
	if aaOpts.Token != nil && !aaOpts.Token.Expired() {
		ctx = metadata.Set(ctx, "Authorization", auth.BearerScheme+aaOpts.Token.AccessToken)
		return a.Client.Call(ctx, req, rsp, opts...)
	}

	// call without an auth token
	return a.Client.Call(ctx, req, rsp, opts...)
}

// AuthClient wraps requests with the auth header
func AuthClient(auth func() auth.Auth, c client.Client) client.Client {
	return &authWrapper{c, auth}
}

// AuthHandler wraps a server handler to perform auth
func AuthHandler(fn func() auth.Auth) server.HandlerWrapper {
	return func(h server.HandlerFunc) server.HandlerFunc {
		return func(ctx context.Context, req server.Request, rsp interface{}) error {
			// get the auth.Auth interface
			a := fn()

			// Check for debug endpoints which should be excluded from auth
			if strings.HasPrefix(req.Endpoint(), "Debug.") {
				return h(ctx, req, rsp)
			}

			// Extract the token if present. Note: if noop is being used
			// then the token can be blank without erroring
			var account *auth.Account
			if header, ok := metadata.Get(ctx, "Authorization"); ok {
				// Ensure the correct scheme is being used
				if !strings.HasPrefix(header, auth.BearerScheme) {
					return errors.Unauthorized(req.Service(), "invalid authorization header. expected Bearer schema")
				}

				// Strip the prefix and inspect the resulting token
				account, _ = a.Inspect(strings.TrimPrefix(header, auth.BearerScheme))
			}

			// Extract the namespace header
			ns, ok := metadata.Get(ctx, "Micro-Namespace")
			if !ok {
				ns = a.Options().Namespace
				ctx = metadata.Set(ctx, "Micro-Namespace", ns)
			}

			// Check the issuer matches the services namespace
			if account != nil && account.Issuer != ns {
				return errors.Forbidden(req.Service(), "Account was not issued by %v", ns)
			}

			// construct the resource
			res := &auth.Resource{
				Type:     "service",
				Name:     req.Service(),
				Endpoint: req.Endpoint(),
			}

			// Verify the caller has access to the resource
			err := a.Verify(account, res, auth.VerifyContext(ctx))
			if err != nil && account != nil {
				return errors.Forbidden(req.Service(), "Forbidden call made to %v:%v by %v", req.Service(), req.Endpoint(), account.ID)
			} else if err != nil {
				return errors.Unauthorized(req.Service(), "Unauthorised call made to %v:%v", req.Service(), req.Endpoint())
			}

			// There is an account, set it in the context
			if account != nil {
				ctx = auth.ContextWithAccount(ctx, account)
			}

			// The user is authorised, allow the call
			return h(ctx, req, rsp)
		}
	}
}

type cacheWrapper struct {
	cacheFn func() *client.Cache
	client.Client
}

// Call executes the request. If the CacheExpiry option was set, the response will be cached using
// a hash of the metadata and request as the key.
func (c *cacheWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	// parse the options
	var options client.CallOptions
	for _, o := range opts {
		o(&options)
	}

	// if the client doesn't have a cacbe setup don't continue
	cache := c.cacheFn()
	if cache == nil {
		return c.Client.Call(ctx, req, rsp, opts...)
	}

	// if the cache expiry is not set, execute the call without the cache
	if options.CacheExpiry == 0 {
		return c.Client.Call(ctx, req, rsp, opts...)
	}

	// if the response is nil don't call the cache since we can't assign the response
	if rsp == nil {
		return c.Client.Call(ctx, req, rsp, opts...)
	}

	// check to see if there is a response cached, if there is assign it
	if r, ok := cache.Get(ctx, &req); ok {
		val := reflect.ValueOf(rsp).Elem()
		val.Set(reflect.ValueOf(r).Elem())
		return nil
	}

	// don't cache the result if there was an error
	if err := c.Client.Call(ctx, req, rsp, opts...); err != nil {
		return err
	}

	// set the result in the cache
	cache.Set(ctx, &req, rsp, options.CacheExpiry)
	return nil
}

// CacheClient wraps requests with the cache wrapper
func CacheClient(cacheFn func() *client.Cache, c client.Client) client.Client {
	return &cacheWrapper{cacheFn, c}
}
<commit_msg>Fix server calling across namespace<commit_after>package wrapper

import (
	"context"
	"reflect"
	"strings"

	"github.com/micro/go-micro/v2/auth"
	"github.com/micro/go-micro/v2/client"
	"github.com/micro/go-micro/v2/debug/stats"
	"github.com/micro/go-micro/v2/debug/trace"
	"github.com/micro/go-micro/v2/errors"
	"github.com/micro/go-micro/v2/metadata"
	"github.com/micro/go-micro/v2/server"
)

type fromServiceWrapper struct {
	client.Client

	// headers to inject
	headers metadata.Metadata
}

var (
	HeaderPrefix = "Micro-"
)

func (f *fromServiceWrapper) setHeaders(ctx context.Context) context.Context {
	// don't overwrite keys
	return metadata.MergeContext(ctx, f.headers, false)
}

func (f *fromServiceWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	ctx = f.setHeaders(ctx)
	return f.Client.Call(ctx, req, rsp, opts...)
}

func (f *fromServiceWrapper) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) {
	ctx = f.setHeaders(ctx)
	return f.Client.Stream(ctx, req, opts...)
}

func (f *fromServiceWrapper) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) error {
	ctx = f.setHeaders(ctx)
	return f.Client.Publish(ctx, p, opts...)
}

// FromService wraps a client to inject service and auth metadata
func FromService(name string, c client.Client) client.Client {
	return &fromServiceWrapper{
		c,
		metadata.Metadata{
			HeaderPrefix + "From-Service": name,
		},
	}
}

// HandlerStats wraps a server handler to generate request/error stats
func HandlerStats(stats stats.Stats) server.HandlerWrapper {
	// return a handler wrapper
	return func(h server.HandlerFunc) server.HandlerFunc {
		// return a function that returns a function
		return func(ctx context.Context, req server.Request, rsp interface{}) error {
			// execute the handler
			err := h(ctx, req, rsp)
			// record the stats
			stats.Record(err)
			// return the error
			return err
		}
	}
}

type traceWrapper struct {
	client.Client

	name  string
	trace trace.Tracer
}

func (c *traceWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	newCtx, s := c.trace.Start(ctx, req.Service()+"."+req.Endpoint())

	s.Type = trace.SpanTypeRequestOutbound
	err := c.Client.Call(newCtx, req, rsp, opts...)
	if err != nil {
		s.Metadata["error"] = err.Error()
	}

	// finish the trace
	c.trace.Finish(s)

	return err
}

// TraceCall is a call tracing wrapper
func TraceCall(name string, t trace.Tracer, c client.Client) client.Client {
	return &traceWrapper{
		name:   name,
		trace:  t,
		Client: c,
	}
}

// TraceHandler wraps a server handler to perform tracing
func TraceHandler(t trace.Tracer) server.HandlerWrapper {
	// return a handler wrapper
	return func(h server.HandlerFunc) server.HandlerFunc {
		// return a function that returns a function
		return func(ctx context.Context, req server.Request, rsp interface{}) error {
			// don't store traces for debug
			if strings.HasPrefix(req.Endpoint(), "Debug.") {
				return h(ctx, req, rsp)
			}

			// get the span
			newCtx, s := t.Start(ctx, req.Service()+"."+req.Endpoint())
			s.Type = trace.SpanTypeRequestInbound

			err := h(newCtx, req, rsp)
			if err != nil {
				s.Metadata["error"] = err.Error()
			}

			// finish
			t.Finish(s)

			return err
		}
	}
}

type authWrapper struct {
	client.Client
	auth func() auth.Auth
}

func (a *authWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	// parse the options
	var options client.CallOptions
	for _, o := range opts {
		o(&options)
	}

	// check to see if the authorization header has already been set.
	// We dont't override the header unless the ServiceToken option has
	// been specified or the header wasn't provided
	if _, ok := metadata.Get(ctx, "Authorization"); ok && !options.ServiceToken {
		return a.Client.Call(ctx, req, rsp, opts...)
	}

	// if auth is nil we won't be able to get an access token, so we execute
	// the request without one.
	aa := a.auth()
	if aa == nil {
		return a.Client.Call(ctx, req, rsp, opts...)
	}

	// set the namespace header if it has not been set (e.g. on a service to service request)
	if _, ok := metadata.Get(ctx, "Micro-Namespace"); !ok {
		ctx = metadata.Set(ctx, "Micro-Namespace", aa.Options().Namespace)
	}

	// check to see if we have a valid access token
	aaOpts := aa.Options()
	if aaOpts.Token != nil && !aaOpts.Token.Expired() {
		ctx = metadata.Set(ctx, "Authorization", auth.BearerScheme+aaOpts.Token.AccessToken)
		return a.Client.Call(ctx, req, rsp, opts...)
	}

	// call without an auth token
	return a.Client.Call(ctx, req, rsp, opts...)
}

// AuthClient wraps requests with the auth header
func AuthClient(auth func() auth.Auth, c client.Client) client.Client {
	return &authWrapper{c, auth}
}

// AuthHandler wraps a server handler to perform auth
func AuthHandler(fn func() auth.Auth) server.HandlerWrapper {
	return func(h server.HandlerFunc) server.HandlerFunc {
		return func(ctx context.Context, req server.Request, rsp interface{}) error {
			// get the auth.Auth interface
			a := fn()

			// Check for debug endpoints which should be excluded from auth
			if strings.HasPrefix(req.Endpoint(), "Debug.") {
				return h(ctx, req, rsp)
			}

			// Extract the token if present. Note: if noop is being used
			// then the token can be blank without erroring
			var account *auth.Account
			if header, ok := metadata.Get(ctx, "Authorization"); ok {
				// Ensure the correct scheme is being used
				if !strings.HasPrefix(header, auth.BearerScheme) {
					return errors.Unauthorized(req.Service(), "invalid authorization header. expected Bearer schema")
				}

				// Strip the prefix and inspect the resulting token
				account, _ = a.Inspect(strings.TrimPrefix(header, auth.BearerScheme))
			}

			// Extract the namespace header
			ns, ok := metadata.Get(ctx, "Micro-Namespace")
			if !ok {
				ns = a.Options().Namespace
				ctx = metadata.Set(ctx, "Micro-Namespace", ns)
			}

			// Check the issuer matches the services namespace. TODO: Stop allowing go.micro to access
			// any namespace and instead check for the server issuer.
			if account != nil && account.Issuer != ns && account.Issuer != "go.micro" {
				return errors.Forbidden(req.Service(), "Account was not issued by %v", ns)
			}

			// construct the resource
			res := &auth.Resource{
				Type:     "service",
				Name:     req.Service(),
				Endpoint: req.Endpoint(),
			}

			// Verify the caller has access to the resource
			err := a.Verify(account, res, auth.VerifyContext(ctx))
			if err != nil && account != nil {
				return errors.Forbidden(req.Service(), "Forbidden call made to %v:%v by %v", req.Service(), req.Endpoint(), account.ID)
			} else if err != nil {
				return errors.Unauthorized(req.Service(), "Unauthorised call made to %v:%v", req.Service(), req.Endpoint())
			}

			// There is an account, set it in the context
			if account != nil {
				ctx = auth.ContextWithAccount(ctx, account)
			}

			// The user is authorised, allow the call
			return h(ctx, req, rsp)
		}
	}
}

type cacheWrapper struct {
	cacheFn func() *client.Cache
	client.Client
}

// Call executes the request. If the CacheExpiry option was set, the response will be cached using
// a hash of the metadata and request as the key.
func (c *cacheWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	// parse the options
	var options client.CallOptions
	for _, o := range opts {
		o(&options)
	}

	// if the client doesn't have a cacbe setup don't continue
	cache := c.cacheFn()
	if cache == nil {
		return c.Client.Call(ctx, req, rsp, opts...)
	}

	// if the cache expiry is not set, execute the call without the cache
	if options.CacheExpiry == 0 {
		return c.Client.Call(ctx, req, rsp, opts...)
	}

	// if the response is nil don't call the cache since we can't assign the response
	if rsp == nil {
		return c.Client.Call(ctx, req, rsp, opts...)
	}

	// check to see if there is a response cached, if there is assign it
	if r, ok := cache.Get(ctx, &req); ok {
		val := reflect.ValueOf(rsp).Elem()
		val.Set(reflect.ValueOf(r).Elem())
		return nil
	}

	// don't cache the result if there was an error
	if err := c.Client.Call(ctx, req, rsp, opts...); err != nil {
		return err
	}

	// set the result in the cache
	cache.Set(ctx, &req, rsp, options.CacheExpiry)
	return nil
}

// CacheClient wraps requests with the cache wrapper
func CacheClient(cacheFn func() *client.Cache, c client.Client) client.Client {
	return &cacheWrapper{cacheFn, c}
}
<|endoftext|>


<commit_before>package iris

import (
	"bufio"
	"fmt"
	"net"
	"net/http"
	"sync"

	"github.com/kataras/go-errors"
	"github.com/kataras/go-fs"
	"github.com/klauspost/compress/gzip"
)

type gzipResponseWriter struct {
	ResponseWriter
	gzipWriter *gzip.Writer
}

var gzpool = sync.Pool{New: func() interface{} { return &gzipResponseWriter{} }}

func acquireGzipResponseWriter(underline ResponseWriter) *gzipResponseWriter {
	w := gzpool.Get().(*gzipResponseWriter)
	w.ResponseWriter = underline
	w.gzipWriter = fs.AcquireGzipWriter(w.ResponseWriter)
	return w
}

func releaseGzipResponseWriter(w *gzipResponseWriter) {
	fs.ReleaseGzipWriter(w.gzipWriter)
	gzpool.Put(w)
}

// Write compresses and writes that data to the underline response writer
func (w *gzipResponseWriter) Write(contents []byte) (int, error) {
	return w.gzipWriter.Write(contents)
}

var rpool = sync.Pool{New: func() interface{} { return &responseWriter{statusCode: StatusOK} }}

func acquireResponseWriter(underline http.ResponseWriter) *responseWriter {
	w := rpool.Get().(*responseWriter)
	w.ResponseWriter = underline
	return w
}

func releaseResponseWriter(w *responseWriter) {
	w.statusCodeSent = false
	w.beforeFlush = nil
	w.statusCode = StatusOK
	rpool.Put(w)
}

// ResponseWriter interface is used by the context to serve an HTTP handler to
// construct an HTTP response.
//
// A ResponseWriter may not be used after the Handler.ServeHTTP method
// has returned.
type ResponseWriter interface {
	http.ResponseWriter
	http.Flusher
	http.Hijacker
	http.CloseNotifier
	http.Pusher

	Writef(format string, a ...interface{}) (n int, err error)
	WriteString(s string) (n int, err error)
	SetContentType(cType string)
	ContentType() string
	StatusCode() int
	SetBeforeFlush(cb func())
	flushResponse()
	clone() ResponseWriter
	writeTo(ResponseWriter)
	releaseMe()
}

// responseWriter is the basic response writer,
// it writes directly to the underline http.ResponseWriter
type responseWriter struct {
	http.ResponseWriter
	statusCode     int  // the saved status code which will be used from the cache service
	statusCodeSent bool // reply header has been (logically) written
	// yes only one callback, we need simplicity here because on EmitError the beforeFlush events should NOT be cleared
	// but the response is cleared.
	// Sometimes is useful to keep the event,
	// so we keep one func only and let the user decide when he/she wants to override it with an empty func before the EmitError (context's behavior)
	beforeFlush func()
}

var _ ResponseWriter = &responseWriter{}

// StatusCode returns the status code header value
func (w *responseWriter) StatusCode() int {
	return w.statusCode
}

// Writef formats according to a format specifier and writes to the response.
//
// Returns the number of bytes written and any write error encountered
func (w *responseWriter) Writef(format string, a ...interface{}) (n int, err error) {
	w.tryWriteHeader()
	return fmt.Fprintf(w.ResponseWriter, format, a...)
}

// WriteString writes a simple string to the response.
//
// Returns the number of bytes written and any write error encountered
func (w *responseWriter) WriteString(s string) (n int, err error) {
	return w.Write([]byte(s))
}

// Write writes to the client
// If WriteHeader has not yet been called, Write calls
// WriteHeader(http.StatusOK) before writing the data. If the Header
// does not contain a Content-Type line, Write adds a Content-Type set
// to the result of passing the initial 512 bytes of written data to
// DetectContentType.
//
// Depending on the HTTP protocol version and the client, calling
// Write or WriteHeader may prevent future reads on the
// Request.Body. For HTTP/1.x requests, handlers should read any
// needed request body data before writing the response. Once the
// headers have been flushed (due to either an explicit Flusher.Flush
// call or writing enough data to trigger a flush), the request body
// may be unavailable. For HTTP/2 requests, the Go HTTP server permits
// handlers to continue to read the request body while concurrently
// writing the response. However, such behavior may not be supported
// by all HTTP/2 clients. Handlers should read before writing if
// possible to maximize compatibility.
func (w *responseWriter) Write(contents []byte) (int, error) {
	w.tryWriteHeader()
	return w.ResponseWriter.Write(contents)
}

// prin to write na benei to write header
// meta to write den ginete edw
// prepei omws kai mono me WriteHeader kai xwris Write na pigenei to status code
// ara...wtf prepei na exw function flushStatusCode kai na elenxei an exei dw9ei status code na to kanei write aliws 200

// WriteHeader sends an HTTP response header with status code.
// If WriteHeader is not called explicitly, the first call to Write
// will trigger an implicit WriteHeader(http.StatusOK).
// Thus explicit calls to WriteHeader are mainly used to
// send error codes.
func (w *responseWriter) WriteHeader(statusCode int) {
	w.statusCode = statusCode
}

// SetBeforeFlush registers the unique callback which called exactly before the response is flushed to the client
func (w *responseWriter) SetBeforeFlush(cb func()) {
	w.beforeFlush = cb
}

func (w *responseWriter) flushResponse() {
	if w.beforeFlush != nil {
		w.beforeFlush()
	}
	w.tryWriteHeader()
}

func (w *responseWriter) tryWriteHeader() {
	if !w.statusCodeSent { // by write
		w.statusCodeSent = true
		w.ResponseWriter.WriteHeader(w.statusCode)
	}
}

// ContentType returns the content type, if not setted returns empty string
func (w *responseWriter) ContentType() string {
	return w.ResponseWriter.Header().Get(contentType)
}

// SetContentType sets the content type header
func (w *responseWriter) SetContentType(cType string) {
	w.ResponseWriter.Header().Set(contentType, cType)
}

// Hijack lets the caller take over the connection.
// After a call to Hijack(), the HTTP server library
// will not do anything else with the connection.
//
// It becomes the caller's responsibility to manage
// and close the connection.
//
// The returned net.Conn may have read or write deadlines
// already set, depending on the configuration of the
// Server. It is the caller's responsibility to set
// or clear those deadlines as needed.
func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
	if h, isHijacker := w.ResponseWriter.(http.Hijacker); isHijacker {
		w.statusCodeSent = true
		return h.Hijack()
	}

	return nil, nil, errors.New("hijack is not supported by this ResponseWriter")
}

// Flush sends any buffered data to the client.
func (w *responseWriter) Flush() {
	// The Flusher interface is implemented by ResponseWriters that allow
	// an HTTP handler to flush buffered data to the client.
	//
	// The default HTTP/1.x and HTTP/2 ResponseWriter implementations
	// support Flusher, but ResponseWriter wrappers may not. Handlers
	// should always test for this ability at runtime.
	//
	// Note that even for ResponseWriters that support Flush,
	// if the client is connected through an HTTP proxy,
	// the buffered data may not reach the client until the response
	// completes.
	if fl, isFlusher := w.ResponseWriter.(http.Flusher); isFlusher {
		fl.Flush()
	}
}

// ErrPushNotSupported is returned by the Push method to
// indicate that HTTP/2 Push support is not available.
var ErrPushNotSupported = errors.New("push feature is not supported by this ResponseWriter")

// Push initiates an HTTP/2 server push. This constructs a synthetic
// request using the given target and options, serializes that request
// into a PUSH_PROMISE frame, then dispatches that request using the
// server's request handler. If opts is nil, default options are used.
//
// The target must either be an absolute path (like "/path") or an absolute
// URL that contains a valid host and the same scheme as the parent request.
// If the target is a path, it will inherit the scheme and host of the
// parent request.
//
// The HTTP/2 spec disallows recursive pushes and cross-authority pushes.
// Push may or may not detect these invalid pushes; however, invalid
// pushes will be detected and canceled by conforming clients.
//
// Handlers that wish to push URL X should call Push before sending any
// data that may trigger a request for URL X. This avoids a race where the
// client issues requests for X before receiving the PUSH_PROMISE for X.
//
// Push returns ErrPushNotSupported if the client has disabled push or if push
// is not supported on the underlying connection.
func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
	if pusher, isPusher := w.ResponseWriter.(http.Pusher); isPusher {
		err := pusher.Push(target, opts)
		if err != nil && err.Error() == http.ErrNotSupported.ErrorString {
			return ErrPushNotSupported
		}
	}
	return ErrPushNotSupported
}

// CloseNotify returns a channel that receives at most a
// single value (true) when the client connection has gone
// away.
//
// CloseNotify may wait to notify until Request.Body has been
// fully read.
//
// After the Handler has returned, there is no guarantee
// that the channel receives a value.
//
// If the protocol is HTTP/1.1 and CloseNotify is called while
// processing an idempotent request (such a GET) while
// HTTP/1.1 pipelining is in use, the arrival of a subsequent
// pipelined request may cause a value to be sent on the
// returned channel. In practice HTTP/1.1 pipelining is not
// enabled in browsers and not seen often in the wild. If this
// is a problem, use HTTP/2 or only use CloseNotify on methods
// such as POST.
func (w *responseWriter) CloseNotify() <-chan bool {
	if notifier, supportsCloseNotify := w.ResponseWriter.(http.CloseNotifier); supportsCloseNotify {
		return notifier.CloseNotify()
	}
	ch := make(chan bool, 1)
	return ch
}

// clone returns a clone of this response writer
// it copies the header, status code, headers and the beforeFlush finally  returns a new ResponseRecorder
func (w *responseWriter) clone() ResponseWriter {
	wc := &responseWriter{}
	wc.ResponseWriter = w.ResponseWriter
	wc.statusCode = w.statusCode
	wc.beforeFlush = w.beforeFlush
	wc.statusCodeSent = w.statusCodeSent
	return wc
}

// writeTo writes a response writer (temp: status code, headers and body) to another response writer
func (w *responseWriter) writeTo(to ResponseWriter) {
	// set the status code, failure status code are first class
	if w.statusCode >= 400 {
		to.WriteHeader(w.statusCode)
	}

	// append the headers
	if w.Header() != nil {
		for k, values := range w.Header() {
			for _, v := range values {
				if to.Header().Get(v) == "" {
					to.Header().Add(k, v)
				}
			}
		}

	}
	// the body is not copied, this writer doesn't supports recording
}

func (w *responseWriter) releaseMe() {
	releaseResponseWriter(w)
}
<commit_msg>fastfix err on nil https://github.com/kataras/iris/issues/565<commit_after>package iris

import (
	"bufio"
	"fmt"
	"net"
	"net/http"
	"sync"

	"github.com/kataras/go-errors"
	"github.com/kataras/go-fs"
	"github.com/klauspost/compress/gzip"
)

type gzipResponseWriter struct {
	ResponseWriter
	gzipWriter *gzip.Writer
}

var gzpool = sync.Pool{New: func() interface{} { return &gzipResponseWriter{} }}

func acquireGzipResponseWriter(underline ResponseWriter) *gzipResponseWriter {
	w := gzpool.Get().(*gzipResponseWriter)
	w.ResponseWriter = underline
	w.gzipWriter = fs.AcquireGzipWriter(w.ResponseWriter)
	return w
}

func releaseGzipResponseWriter(w *gzipResponseWriter) {
	fs.ReleaseGzipWriter(w.gzipWriter)
	gzpool.Put(w)
}

// Write compresses and writes that data to the underline response writer
func (w *gzipResponseWriter) Write(contents []byte) (int, error) {
	return w.gzipWriter.Write(contents)
}

var rpool = sync.Pool{New: func() interface{} { return &responseWriter{statusCode: StatusOK} }}

func acquireResponseWriter(underline http.ResponseWriter) *responseWriter {
	w := rpool.Get().(*responseWriter)
	w.ResponseWriter = underline
	return w
}

func releaseResponseWriter(w *responseWriter) {
	w.statusCodeSent = false
	w.beforeFlush = nil
	w.statusCode = StatusOK
	rpool.Put(w)
}

// ResponseWriter interface is used by the context to serve an HTTP handler to
// construct an HTTP response.
//
// A ResponseWriter may not be used after the Handler.ServeHTTP method
// has returned.
type ResponseWriter interface {
	http.ResponseWriter
	http.Flusher
	http.Hijacker
	http.CloseNotifier
	http.Pusher

	Writef(format string, a ...interface{}) (n int, err error)
	WriteString(s string) (n int, err error)
	SetContentType(cType string)
	ContentType() string
	StatusCode() int
	SetBeforeFlush(cb func())
	flushResponse()
	clone() ResponseWriter
	writeTo(ResponseWriter)
	releaseMe()
}

// responseWriter is the basic response writer,
// it writes directly to the underline http.ResponseWriter
type responseWriter struct {
	http.ResponseWriter
	statusCode     int  // the saved status code which will be used from the cache service
	statusCodeSent bool // reply header has been (logically) written
	// yes only one callback, we need simplicity here because on EmitError the beforeFlush events should NOT be cleared
	// but the response is cleared.
	// Sometimes is useful to keep the event,
	// so we keep one func only and let the user decide when he/she wants to override it with an empty func before the EmitError (context's behavior)
	beforeFlush func()
}

var _ ResponseWriter = &responseWriter{}

// StatusCode returns the status code header value
func (w *responseWriter) StatusCode() int {
	return w.statusCode
}

// Writef formats according to a format specifier and writes to the response.
//
// Returns the number of bytes written and any write error encountered
func (w *responseWriter) Writef(format string, a ...interface{}) (n int, err error) {
	w.tryWriteHeader()
	return fmt.Fprintf(w.ResponseWriter, format, a...)
}

// WriteString writes a simple string to the response.
//
// Returns the number of bytes written and any write error encountered
func (w *responseWriter) WriteString(s string) (n int, err error) {
	return w.Write([]byte(s))
}

// Write writes to the client
// If WriteHeader has not yet been called, Write calls
// WriteHeader(http.StatusOK) before writing the data. If the Header
// does not contain a Content-Type line, Write adds a Content-Type set
// to the result of passing the initial 512 bytes of written data to
// DetectContentType.
//
// Depending on the HTTP protocol version and the client, calling
// Write or WriteHeader may prevent future reads on the
// Request.Body. For HTTP/1.x requests, handlers should read any
// needed request body data before writing the response. Once the
// headers have been flushed (due to either an explicit Flusher.Flush
// call or writing enough data to trigger a flush), the request body
// may be unavailable. For HTTP/2 requests, the Go HTTP server permits
// handlers to continue to read the request body while concurrently
// writing the response. However, such behavior may not be supported
// by all HTTP/2 clients. Handlers should read before writing if
// possible to maximize compatibility.
func (w *responseWriter) Write(contents []byte) (int, error) {
	w.tryWriteHeader()
	return w.ResponseWriter.Write(contents)
}

// prin to write na benei to write header
// meta to write den ginete edw
// prepei omws kai mono me WriteHeader kai xwris Write na pigenei to status code
// ara...wtf prepei na exw function flushStatusCode kai na elenxei an exei dw9ei status code na to kanei write aliws 200

// WriteHeader sends an HTTP response header with status code.
// If WriteHeader is not called explicitly, the first call to Write
// will trigger an implicit WriteHeader(http.StatusOK).
// Thus explicit calls to WriteHeader are mainly used to
// send error codes.
func (w *responseWriter) WriteHeader(statusCode int) {
	w.statusCode = statusCode
}

// SetBeforeFlush registers the unique callback which called exactly before the response is flushed to the client
func (w *responseWriter) SetBeforeFlush(cb func()) {
	w.beforeFlush = cb
}

func (w *responseWriter) flushResponse() {
	if w.beforeFlush != nil {
		w.beforeFlush()
	}
	w.tryWriteHeader()
}

func (w *responseWriter) tryWriteHeader() {
	if !w.statusCodeSent { // by write
		w.statusCodeSent = true
		w.ResponseWriter.WriteHeader(w.statusCode)
	}
}

// ContentType returns the content type, if not setted returns empty string
func (w *responseWriter) ContentType() string {
	return w.ResponseWriter.Header().Get(contentType)
}

// SetContentType sets the content type header
func (w *responseWriter) SetContentType(cType string) {
	w.ResponseWriter.Header().Set(contentType, cType)
}

// Hijack lets the caller take over the connection.
// After a call to Hijack(), the HTTP server library
// will not do anything else with the connection.
//
// It becomes the caller's responsibility to manage
// and close the connection.
//
// The returned net.Conn may have read or write deadlines
// already set, depending on the configuration of the
// Server. It is the caller's responsibility to set
// or clear those deadlines as needed.
func (w *responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
	if h, isHijacker := w.ResponseWriter.(http.Hijacker); isHijacker {
		w.statusCodeSent = true
		return h.Hijack()
	}

	return nil, nil, errors.New("hijack is not supported by this ResponseWriter")
}

// Flush sends any buffered data to the client.
func (w *responseWriter) Flush() {
	// The Flusher interface is implemented by ResponseWriters that allow
	// an HTTP handler to flush buffered data to the client.
	//
	// The default HTTP/1.x and HTTP/2 ResponseWriter implementations
	// support Flusher, but ResponseWriter wrappers may not. Handlers
	// should always test for this ability at runtime.
	//
	// Note that even for ResponseWriters that support Flush,
	// if the client is connected through an HTTP proxy,
	// the buffered data may not reach the client until the response
	// completes.
	if fl, isFlusher := w.ResponseWriter.(http.Flusher); isFlusher {
		fl.Flush()
	}
}

// ErrPushNotSupported is returned by the Push method to
// indicate that HTTP/2 Push support is not available.
var ErrPushNotSupported = errors.New("push feature is not supported by this ResponseWriter")

// Push initiates an HTTP/2 server push. This constructs a synthetic
// request using the given target and options, serializes that request
// into a PUSH_PROMISE frame, then dispatches that request using the
// server's request handler. If opts is nil, default options are used.
//
// The target must either be an absolute path (like "/path") or an absolute
// URL that contains a valid host and the same scheme as the parent request.
// If the target is a path, it will inherit the scheme and host of the
// parent request.
//
// The HTTP/2 spec disallows recursive pushes and cross-authority pushes.
// Push may or may not detect these invalid pushes; however, invalid
// pushes will be detected and canceled by conforming clients.
//
// Handlers that wish to push URL X should call Push before sending any
// data that may trigger a request for URL X. This avoids a race where the
// client issues requests for X before receiving the PUSH_PROMISE for X.
//
// Push returns ErrPushNotSupported if the client has disabled push or if push
// is not supported on the underlying connection.
func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
	if pusher, isPusher := w.ResponseWriter.(http.Pusher); isPusher {
		err := pusher.Push(target, opts)
		if err != nil && err.Error() == http.ErrNotSupported.ErrorString {
			return ErrPushNotSupported
		}
		return err
	}
	return ErrPushNotSupported
}

// CloseNotify returns a channel that receives at most a
// single value (true) when the client connection has gone
// away.
//
// CloseNotify may wait to notify until Request.Body has been
// fully read.
//
// After the Handler has returned, there is no guarantee
// that the channel receives a value.
//
// If the protocol is HTTP/1.1 and CloseNotify is called while
// processing an idempotent request (such a GET) while
// HTTP/1.1 pipelining is in use, the arrival of a subsequent
// pipelined request may cause a value to be sent on the
// returned channel. In practice HTTP/1.1 pipelining is not
// enabled in browsers and not seen often in the wild. If this
// is a problem, use HTTP/2 or only use CloseNotify on methods
// such as POST.
func (w *responseWriter) CloseNotify() <-chan bool {
	if notifier, supportsCloseNotify := w.ResponseWriter.(http.CloseNotifier); supportsCloseNotify {
		return notifier.CloseNotify()
	}
	ch := make(chan bool, 1)
	return ch
}

// clone returns a clone of this response writer
// it copies the header, status code, headers and the beforeFlush finally  returns a new ResponseRecorder
func (w *responseWriter) clone() ResponseWriter {
	wc := &responseWriter{}
	wc.ResponseWriter = w.ResponseWriter
	wc.statusCode = w.statusCode
	wc.beforeFlush = w.beforeFlush
	wc.statusCodeSent = w.statusCodeSent
	return wc
}

// writeTo writes a response writer (temp: status code, headers and body) to another response writer
func (w *responseWriter) writeTo(to ResponseWriter) {
	// set the status code, failure status code are first class
	if w.statusCode >= 400 {
		to.WriteHeader(w.statusCode)
	}

	// append the headers
	if w.Header() != nil {
		for k, values := range w.Header() {
			for _, v := range values {
				if to.Header().Get(v) == "" {
					to.Header().Add(k, v)
				}
			}
		}

	}
	// the body is not copied, this writer doesn't supports recording
}

func (w *responseWriter) releaseMe() {
	releaseResponseWriter(w)
}
<|endoftext|>


<commit_before>package datacounter

import (
	"bufio"
	"fmt"
	"net"
	"net/http"
	"sync/atomic"
	"time"
)

// ResponseWriterCounter is counter for http.ResponseWriter
type ResponseWriterCounter struct {
	http.ResponseWriter
	count   uint64
	started time.Time
}

// NewResponseWriterCounter function create new ResponseWriterCounter
func NewResponseWriterCounter(rw http.ResponseWriter) *ResponseWriterCounter {
	return &ResponseWriterCounter{
		ResponseWriter: rw,
		started:        time.Now(),
	}
}

// Write returns underlying Write result, while counting data size
func (counter *ResponseWriterCounter) Write(buf []byte) (int, error) {
	n, err := counter.ResponseWriter.Write(buf)
	atomic.AddUint64(&counter.count, uint64(n))
	return n, err
}

// Header returns underlying Header result
func (counter *ResponseWriterCounter) Header() http.Header {
	return counter.ResponseWriter.Header()
}

// WriteHeader returns underlying WriteHeader, while setting Runtime header
func (counter *ResponseWriterCounter) WriteHeader(statusCode int) {
	counter.Header().Set("X-Runtime", fmt.Sprintf("%.6f", time.Since(counter.started).Seconds()))
	counter.ResponseWriter.WriteHeader(statusCode)
}

// Hijack returns underlying Hijack
func (counter *ResponseWriterCounter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
	return counter.ResponseWriter.(http.Hijacker).Hijack()
}

// Count function return counted bytes
func (counter *ResponseWriterCounter) Count() uint64 {
	return atomic.LoadUint64(&counter.count)
}

// Started returns started value
func (counter *ResponseWriterCounter) Started() time.Time {
	return counter.started
}
<commit_msg>ResponseWriterCounter: return statusCode<commit_after>package datacounter

import (
	"bufio"
	"fmt"
	"net"
	"net/http"
	"sync/atomic"
	"time"
)

// ResponseWriterCounter is counter for http.ResponseWriter
type ResponseWriterCounter struct {
	http.ResponseWriter
	count      uint64
	started    time.Time
	statusCode int
}

// NewResponseWriterCounter function create new ResponseWriterCounter
func NewResponseWriterCounter(rw http.ResponseWriter) *ResponseWriterCounter {
	return &ResponseWriterCounter{
		ResponseWriter: rw,
		started:        time.Now(),
	}
}

// Write returns underlying Write result, while counting data size
func (counter *ResponseWriterCounter) Write(buf []byte) (int, error) {
	n, err := counter.ResponseWriter.Write(buf)
	atomic.AddUint64(&counter.count, uint64(n))
	return n, err
}

// Header returns underlying Header result
func (counter *ResponseWriterCounter) Header() http.Header {
	return counter.ResponseWriter.Header()
}

// WriteHeader returns underlying WriteHeader, while setting Runtime header
func (counter *ResponseWriterCounter) WriteHeader(statusCode int) {
	counter.Header().Set("X-Runtime", fmt.Sprintf("%.6f", time.Since(counter.started).Seconds()))
	counter.ResponseWriter.WriteHeader(statusCode)
}

// Hijack returns underlying Hijack
func (counter *ResponseWriterCounter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
	return counter.ResponseWriter.(http.Hijacker).Hijack()
}

// Count function return counted bytes
func (counter *ResponseWriterCounter) Count() uint64 {
	return atomic.LoadUint64(&counter.count)
}

// Started returns started value
func (counter *ResponseWriterCounter) Started() time.Time {
	return counter.started
}

// StatusCode returns sent status code
func (counter *ResponseWriterCounter) StatusCode() int {
	return counter.statusCode
}
<|endoftext|>


<commit_before>package redis

import "time"

// NewCmdResult returns a Cmd initialised with val and err for testing
func NewCmdResult(val interface{}, err error) *Cmd {
	var cmd Cmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewSliceResult returns a SliceCmd initialised with val and err for testing
func NewSliceResult(val []interface{}, err error) *SliceCmd {
	var cmd SliceCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewStatusResult returns a StatusCmd initialised with val and err for testing
func NewStatusResult(val string, err error) *StatusCmd {
	var cmd StatusCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewIntResult returns an IntCmd initialised with val and err for testing
func NewIntResult(val int64, err error) *IntCmd {
	var cmd IntCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewDurationResult returns a DurationCmd initialised with val and err for testing
func NewDurationResult(val time.Duration, err error) *DurationCmd {
	var cmd DurationCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewBoolResult returns a BoolCmd initialised with val and err for testing
func NewBoolResult(val bool, err error) *BoolCmd {
	var cmd BoolCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewStringResult returns a StringCmd initialised with val and err for testing
func NewStringResult(val string, err error) *StringCmd {
	var cmd StringCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewFloatResult returns a FloatCmd initialised with val and err for testing
func NewFloatResult(val float64, err error) *FloatCmd {
	var cmd FloatCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewStringSliceResult returns a StringSliceCmd initialised with val and err for testing
func NewStringSliceResult(val []string, err error) *StringSliceCmd {
	var cmd StringSliceCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewBoolSliceResult returns a BoolSliceCmd initialised with val and err for testing
func NewBoolSliceResult(val []bool, err error) *BoolSliceCmd {
	var cmd BoolSliceCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewStringStringMapResult returns a StringStringMapCmd initialised with val and err for testing
func NewStringStringMapResult(val map[string]string, err error) *StringStringMapCmd {
	var cmd StringStringMapCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewStringIntMapCmdResult returns a StringIntMapCmd initialised with val and err for testing
func NewStringIntMapCmdResult(val map[string]int64, err error) *StringIntMapCmd {
	var cmd StringIntMapCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewZSliceCmdResult returns a ZSliceCmd initialised with val and err for testing
func NewZSliceCmdResult(val []Z, err error) *ZSliceCmd {
	var cmd ZSliceCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewScanCmdResult returns a ScanCmd initialised with val and err for testing
func NewScanCmdResult(keys []string, cursor uint64, err error) *ScanCmd {
	var cmd ScanCmd
	cmd.page = keys
	cmd.cursor = cursor
	cmd.setErr(err)
	return &cmd
}

// NewClusterSlotsCmdResult returns a ClusterSlotsCmd initialised with val and err for testing
func NewClusterSlotsCmdResult(val []ClusterSlot, err error) *ClusterSlotsCmd {
	var cmd ClusterSlotsCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewGeoLocationCmdResult returns a GeoLocationCmd initialised with val and err for testing
func NewGeoLocationCmdResult(val []GeoLocation, err error) *GeoLocationCmd {
	var cmd GeoLocationCmd
	cmd.locations = val
	cmd.setErr(err)
	return &cmd
}

// NewCommandsInfoCmdResult returns a CommandsInfoCmd initialised with val and err for testing
func NewCommandsInfoCmdResult(val map[string]*CommandInfo, err error) *CommandsInfoCmd {
	var cmd CommandsInfoCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}
<commit_msg>Add NewZWithKeyCmdResult to initialize ZWithKeyCmd for testing<commit_after>package redis

import "time"

// NewCmdResult returns a Cmd initialised with val and err for testing
func NewCmdResult(val interface{}, err error) *Cmd {
	var cmd Cmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewSliceResult returns a SliceCmd initialised with val and err for testing
func NewSliceResult(val []interface{}, err error) *SliceCmd {
	var cmd SliceCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewStatusResult returns a StatusCmd initialised with val and err for testing
func NewStatusResult(val string, err error) *StatusCmd {
	var cmd StatusCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewIntResult returns an IntCmd initialised with val and err for testing
func NewIntResult(val int64, err error) *IntCmd {
	var cmd IntCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewDurationResult returns a DurationCmd initialised with val and err for testing
func NewDurationResult(val time.Duration, err error) *DurationCmd {
	var cmd DurationCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewBoolResult returns a BoolCmd initialised with val and err for testing
func NewBoolResult(val bool, err error) *BoolCmd {
	var cmd BoolCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewStringResult returns a StringCmd initialised with val and err for testing
func NewStringResult(val string, err error) *StringCmd {
	var cmd StringCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewFloatResult returns a FloatCmd initialised with val and err for testing
func NewFloatResult(val float64, err error) *FloatCmd {
	var cmd FloatCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewStringSliceResult returns a StringSliceCmd initialised with val and err for testing
func NewStringSliceResult(val []string, err error) *StringSliceCmd {
	var cmd StringSliceCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewBoolSliceResult returns a BoolSliceCmd initialised with val and err for testing
func NewBoolSliceResult(val []bool, err error) *BoolSliceCmd {
	var cmd BoolSliceCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewStringStringMapResult returns a StringStringMapCmd initialised with val and err for testing
func NewStringStringMapResult(val map[string]string, err error) *StringStringMapCmd {
	var cmd StringStringMapCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewStringIntMapCmdResult returns a StringIntMapCmd initialised with val and err for testing
func NewStringIntMapCmdResult(val map[string]int64, err error) *StringIntMapCmd {
	var cmd StringIntMapCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewZSliceCmdResult returns a ZSliceCmd initialised with val and err for testing
func NewZSliceCmdResult(val []Z, err error) *ZSliceCmd {
	var cmd ZSliceCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewZWithKeyCmdResult returns a NewZWithKeyCmd initialised with val and err for testing
func NewZWithKeyCmdResult(val *ZWithKey, err error) *ZWithKeyCmd {
	var cmd ZWithKeyCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewScanCmdResult returns a ScanCmd initialised with val and err for testing
func NewScanCmdResult(keys []string, cursor uint64, err error) *ScanCmd {
	var cmd ScanCmd
	cmd.page = keys
	cmd.cursor = cursor
	cmd.setErr(err)
	return &cmd
}

// NewClusterSlotsCmdResult returns a ClusterSlotsCmd initialised with val and err for testing
func NewClusterSlotsCmdResult(val []ClusterSlot, err error) *ClusterSlotsCmd {
	var cmd ClusterSlotsCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}

// NewGeoLocationCmdResult returns a GeoLocationCmd initialised with val and err for testing
func NewGeoLocationCmdResult(val []GeoLocation, err error) *GeoLocationCmd {
	var cmd GeoLocationCmd
	cmd.locations = val
	cmd.setErr(err)
	return &cmd
}

// NewCommandsInfoCmdResult returns a CommandsInfoCmd initialised with val and err for testing
func NewCommandsInfoCmdResult(val map[string]*CommandInfo, err error) *CommandsInfoCmd {
	var cmd CommandsInfoCmd
	cmd.val = val
	cmd.setErr(err)
	return &cmd
}
<|endoftext|>


<commit_before>package rardecode

import (
	"bytes"
	"encoding/binary"
	"hash/crc32"
	"io"
)

const (
	fileSize = 0x1000000

	vmGlobalAddr      = 0x3C000
	vmGlobalSize      = 0x02000
	vmFixedGlobalSize = 0x40
)

// v3Filter is the interface type for RAR V3 filters.
// v3Filter performs the same function as the filter type, except that it also takes
// the initial register values r, and global data as input for the RAR V3 VM.
type v3Filter func(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error)

var (
	// standardV3Filters is a list of known filters. We can replace the use of a vm
	// filter with a custom filter function.
	standardV3Filters = []struct {
		crc uint32   // crc of code byte slice for filter
		len int      // length of code byte slice for filter
		f   v3Filter // replacement filter function
	}{
		{0xad576887, 53, e8FilterV3},
		{0x3cd7e57e, 57, e8e9FilterV3},
		{0x0e06077d, 29, deltaFilterV3},
		{0xbc85e701, 216, filterAudioV3},
	}
)

func filterE8(c byte, v5 bool, buf []byte, offset int64) ([]byte, error) {
	off := int32(offset)
	for b := buf; len(b) >= 5; {
		ch := b[0]
		b = b[1:]
		off++
		if ch != 0xe8 && ch != c {
			continue
		}
		if v5 {
			off %= fileSize
		}
		addr := int32(binary.LittleEndian.Uint32(b))
		if addr < 0 {
			if addr+off >= 0 {
				binary.LittleEndian.PutUint32(b, uint32(addr+fileSize))
			}
		} else if addr < fileSize {
			binary.LittleEndian.PutUint32(b, uint32(addr-off))
		}
		off += 4
		b = b[4:]
	}
	return buf, nil
}

func e8FilterV3(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	return filterE8(0xe8, false, buf, offset)
}

func e8e9FilterV3(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	return filterE8(0xe9, false, buf, offset)
}

func filterDelta(n int, buf []byte) ([]byte, error) {
	var res []byte
	l := len(buf)
	if cap(buf) >= 2*l {
		res = buf[l : 2*l] // use unused capacity
	} else {
		res = make([]byte, l, 2*l)
	}

	i := 0
	for j := 0; j < n; j++ {
		var c byte
		for k := j; k < len(res); k += n {
			c -= buf[i]
			i++
			res[k] = c
		}
	}
	return res, nil
}

func deltaFilterV3(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	return filterDelta(int(r[0]), buf)
}

func abs(n int) int {
	if n < 0 {
		n = -n
	}
	return n
}

func filterAudioV3(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	var res []byte
	l := len(buf)
	if cap(buf) >= 2*l {
		res = buf[l : 2*l] // use unused capacity
	} else {
		res = make([]byte, l, 2*l)
	}

	chans := int(r[0])
	for c := 0; c < chans; c++ {
		var prevByte, byteCount int
		var diff [7]int
		var d, k [3]int

		for i := c; i < len(res); i += chans {
			predicted := prevByte<<3 + k[0]*d[0] + k[1]*d[1] + k[2]*d[2]
			predicted = int(int8(predicted >> 3))

			curByte := int(int8(buf[0]))
			buf = buf[1:]
			predicted -= curByte
			res[i] = uint8(predicted)

			dd := curByte << 3
			diff[0] += abs(dd)
			diff[1] += abs(dd - d[0])
			diff[2] += abs(dd + d[0])
			diff[3] += abs(dd - d[1])
			diff[4] += abs(dd + d[1])
			diff[5] += abs(dd - d[2])
			diff[6] += abs(dd + d[2])

			prevDelta := int(int8(predicted - prevByte))
			prevByte = predicted
			d[2] = d[1]
			d[1] = prevDelta - d[0]
			d[0] = prevDelta

			if byteCount&0x1f == 0 {
				min := diff[0]
				diff[0] = 0
				n := 0
				for j := 1; j < len(diff); j++ {
					if diff[j] < min {
						min = diff[j]
						n = j
					}
					diff[j] = 0
				}
				n--
				if n >= 0 {
					m := n / 2
					if n%2 == 0 {
						if k[m] >= -16 {
							k[m]--
						}
					} else {
						if k[m] < 16 {
							k[m]++
						}
					}
				}
			}
			byteCount++
		}

	}
	return res, nil
}

func filterArm(buf []byte, offset int64) ([]byte, error) {
	for i := 0; len(buf)-i > 3; i += 4 {
		if buf[i+3] == 0xeb {
			n := uint(buf[i])
			n += uint(buf[i+1]) * 0x100
			n += uint(buf[i+2]) * 0x10000
			n -= (uint(offset) + uint(i)) / 4
			buf[i] = byte(n)
			buf[i+1] = byte(n >> 8)
			buf[i+2] = byte(n >> 16)
		}
	}
	return buf, nil
}

type vmFilter struct {
	execCount uint32
	global    []byte
	static    []byte
	code      []command
}

// execute implements v3filter type for VM based RAR 3 filters.
func (f *vmFilter) execute(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	if len(buf) > vmGlobalAddr {
		return buf, errInvalidFilter
	}
	v := newVM(buf)

	// register setup
	v.r[3] = vmGlobalAddr
	v.r[4] = uint32(len(buf))
	v.r[5] = f.execCount
	for i, n := range r {
		v.r[i] = n
	}

	// vm global data memory block
	vg := v.m[vmGlobalAddr : vmGlobalAddr+vmGlobalSize]

	// initialize fixed global memory
	for i, n := range v.r[:vmRegs-1] {
		binary.LittleEndian.PutUint32(vg[i*4:], n)
	}
	binary.LittleEndian.PutUint32(vg[0x1c:], uint32(len(buf)))
	binary.LittleEndian.PutUint64(vg[0x24:], uint64(offset))
	binary.LittleEndian.PutUint32(vg[0x2c:], f.execCount)

	// registers
	v.r[6] = uint32(offset)

	// copy program global memory
	var n int
	if len(f.global) > 0 {
		n = copy(vg[vmFixedGlobalSize:], f.global) // use saved global instead
	} else {
		n = copy(vg[vmFixedGlobalSize:], global)
	}
	copy(vg[vmFixedGlobalSize+n:], f.static)

	v.execute(f.code)

	f.execCount++

	// keep largest global buffer
	if cap(global) > cap(f.global) {
		f.global = global[:0]
	} else if len(f.global) > 0 {
		f.global = f.global[:0]
	}

	// check for global data to be saved for next program execution
	globalSize := binary.LittleEndian.Uint32(vg[0x30:])
	if globalSize > 0 {
		if globalSize > vmGlobalSize-vmFixedGlobalSize {
			globalSize = vmGlobalSize - vmFixedGlobalSize
		}
		if cap(f.global) < int(globalSize) {
			f.global = make([]byte, globalSize)
		} else {
			f.global = f.global[:globalSize]
		}
		copy(f.global, vg[vmFixedGlobalSize:])
	}

	// find program output
	length := binary.LittleEndian.Uint32(vg[0x1c:]) & vmMask
	start := binary.LittleEndian.Uint32(vg[0x20:]) & vmMask
	if start+length > vmSize {
		// TODO: error
		start = 0
		length = 0
	}
	if start != 0 && cap(v.m) > cap(buf) {
		// Initial buffer was to small for vm.
		// Copy output to beginning of vm memory so that decodeReader
		// will re-use the newly allocated vm memory and we will not
		// have to reallocate again next time.
		copy(v.m, v.m[start:start+length])
		start = 0
	}
	return v.m[start : start+length], nil
}

// getV3Filter returns a V3 filter function from a code byte slice.
func getV3Filter(code []byte) (v3Filter, error) {
	// check if filter is a known standard filter
	c := crc32.ChecksumIEEE(code)
	for _, f := range standardV3Filters {
		if f.crc == c && f.len == len(code) {
			return f.f, nil
		}
	}

	// create new vm filter
	f := new(vmFilter)
	r := newRarBitReader(bytes.NewReader(code[1:])) // skip first xor byte check

	// read static data
	n, err := r.readBits(1)
	if err != nil {
		return nil, err
	}
	if n > 0 {
		m, err := r.readUint32()
		if err != nil {
			return nil, err
		}
		f.static = make([]byte, m+1)
		err = r.readFull(f.static)
		if err != nil {
			return nil, err
		}
	}

	f.code, err = readCommands(r)
	if err == io.EOF {
		err = nil
	}

	return f.execute, err
}
<commit_msg>Add native implementation of RGB filter<commit_after>package rardecode

import (
	"bytes"
	"encoding/binary"
	"hash/crc32"
	"io"
)

const (
	fileSize = 0x1000000

	vmGlobalAddr      = 0x3C000
	vmGlobalSize      = 0x02000
	vmFixedGlobalSize = 0x40
)

// v3Filter is the interface type for RAR V3 filters.
// v3Filter performs the same function as the filter type, except that it also takes
// the initial register values r, and global data as input for the RAR V3 VM.
type v3Filter func(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error)

var (
	// standardV3Filters is a list of known filters. We can replace the use of a vm
	// filter with a custom filter function.
	standardV3Filters = []struct {
		crc uint32   // crc of code byte slice for filter
		len int      // length of code byte slice for filter
		f   v3Filter // replacement filter function
	}{
		{0xad576887, 53, e8FilterV3},
		{0x3cd7e57e, 57, e8e9FilterV3},
		{0x0e06077d, 29, deltaFilterV3},
		{0x1c2c5dc8, 149, filterRGBV3},
		{0xbc85e701, 216, filterAudioV3},
	}
)

func filterE8(c byte, v5 bool, buf []byte, offset int64) ([]byte, error) {
	off := int32(offset)
	for b := buf; len(b) >= 5; {
		ch := b[0]
		b = b[1:]
		off++
		if ch != 0xe8 && ch != c {
			continue
		}
		if v5 {
			off %= fileSize
		}
		addr := int32(binary.LittleEndian.Uint32(b))
		if addr < 0 {
			if addr+off >= 0 {
				binary.LittleEndian.PutUint32(b, uint32(addr+fileSize))
			}
		} else if addr < fileSize {
			binary.LittleEndian.PutUint32(b, uint32(addr-off))
		}
		off += 4
		b = b[4:]
	}
	return buf, nil
}

func e8FilterV3(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	return filterE8(0xe8, false, buf, offset)
}

func e8e9FilterV3(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	return filterE8(0xe9, false, buf, offset)
}

func filterDelta(n int, buf []byte) ([]byte, error) {
	var res []byte
	l := len(buf)
	if cap(buf) >= 2*l {
		res = buf[l : 2*l] // use unused capacity
	} else {
		res = make([]byte, l, 2*l)
	}

	i := 0
	for j := 0; j < n; j++ {
		var c byte
		for k := j; k < len(res); k += n {
			c -= buf[i]
			i++
			res[k] = c
		}
	}
	return res, nil
}

func deltaFilterV3(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	return filterDelta(int(r[0]), buf)
}

func abs(n int) int {
	if n < 0 {
		n = -n
	}
	return n
}

func filterRGBV3(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	width := int(r[0] - 3)
	posR := int(r[1])
	if posR < 0 || width < 0 {
		return buf, nil
	}

	var res []byte
	l := len(buf)
	if cap(buf) >= 2*l {
		res = buf[l : 2*l] // use unused capacity
	} else {
		res = make([]byte, l, 2*l)
	}

	for c := 0; c < 3; c++ {
		var prevByte int
		for i := c; i < len(res); i += 3 {
			var predicted int
			upperPos := i - width
			if upperPos >= 3 {
				upperByte := int(res[upperPos])
				upperLeftByte := int(res[upperPos-3])
				predicted = prevByte + upperByte - upperLeftByte
				pa := abs(predicted - prevByte)
				pb := abs(predicted - upperByte)
				pc := abs(predicted - upperLeftByte)
				if pa <= pb && pa <= pc {
					predicted = prevByte
				} else if pb <= pc {
					predicted = upperByte
				} else {
					predicted = upperLeftByte
				}
			} else {
				predicted = prevByte
			}
			prevByte = (predicted - int(buf[0])) & 0xFF
			res[i] = uint8(prevByte)
			buf = buf[1:]
		}

	}
	for i := posR; i < len(res)-2; i += 3 {
		c := res[i+1]
		res[i] += c
		res[i+2] += c
	}
	return res, nil
}

func filterAudioV3(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	var res []byte
	l := len(buf)
	if cap(buf) >= 2*l {
		res = buf[l : 2*l] // use unused capacity
	} else {
		res = make([]byte, l, 2*l)
	}

	chans := int(r[0])
	for c := 0; c < chans; c++ {
		var prevByte, byteCount int
		var diff [7]int
		var d, k [3]int

		for i := c; i < len(res); i += chans {
			predicted := prevByte<<3 + k[0]*d[0] + k[1]*d[1] + k[2]*d[2]
			predicted = int(int8(predicted >> 3))

			curByte := int(int8(buf[0]))
			buf = buf[1:]
			predicted -= curByte
			res[i] = uint8(predicted)

			dd := curByte << 3
			diff[0] += abs(dd)
			diff[1] += abs(dd - d[0])
			diff[2] += abs(dd + d[0])
			diff[3] += abs(dd - d[1])
			diff[4] += abs(dd + d[1])
			diff[5] += abs(dd - d[2])
			diff[6] += abs(dd + d[2])

			prevDelta := int(int8(predicted - prevByte))
			prevByte = predicted
			d[2] = d[1]
			d[1] = prevDelta - d[0]
			d[0] = prevDelta

			if byteCount&0x1f == 0 {
				min := diff[0]
				diff[0] = 0
				n := 0
				for j := 1; j < len(diff); j++ {
					if diff[j] < min {
						min = diff[j]
						n = j
					}
					diff[j] = 0
				}
				n--
				if n >= 0 {
					m := n / 2
					if n%2 == 0 {
						if k[m] >= -16 {
							k[m]--
						}
					} else {
						if k[m] < 16 {
							k[m]++
						}
					}
				}
			}
			byteCount++
		}

	}
	return res, nil
}

func filterArm(buf []byte, offset int64) ([]byte, error) {
	for i := 0; len(buf)-i > 3; i += 4 {
		if buf[i+3] == 0xeb {
			n := uint(buf[i])
			n += uint(buf[i+1]) * 0x100
			n += uint(buf[i+2]) * 0x10000
			n -= (uint(offset) + uint(i)) / 4
			buf[i] = byte(n)
			buf[i+1] = byte(n >> 8)
			buf[i+2] = byte(n >> 16)
		}
	}
	return buf, nil
}

type vmFilter struct {
	execCount uint32
	global    []byte
	static    []byte
	code      []command
}

// execute implements v3filter type for VM based RAR 3 filters.
func (f *vmFilter) execute(r map[int]uint32, global, buf []byte, offset int64) ([]byte, error) {
	if len(buf) > vmGlobalAddr {
		return buf, errInvalidFilter
	}
	v := newVM(buf)

	// register setup
	v.r[3] = vmGlobalAddr
	v.r[4] = uint32(len(buf))
	v.r[5] = f.execCount
	for i, n := range r {
		v.r[i] = n
	}

	// vm global data memory block
	vg := v.m[vmGlobalAddr : vmGlobalAddr+vmGlobalSize]

	// initialize fixed global memory
	for i, n := range v.r[:vmRegs-1] {
		binary.LittleEndian.PutUint32(vg[i*4:], n)
	}
	binary.LittleEndian.PutUint32(vg[0x1c:], uint32(len(buf)))
	binary.LittleEndian.PutUint64(vg[0x24:], uint64(offset))
	binary.LittleEndian.PutUint32(vg[0x2c:], f.execCount)

	// registers
	v.r[6] = uint32(offset)

	// copy program global memory
	var n int
	if len(f.global) > 0 {
		n = copy(vg[vmFixedGlobalSize:], f.global) // use saved global instead
	} else {
		n = copy(vg[vmFixedGlobalSize:], global)
	}
	copy(vg[vmFixedGlobalSize+n:], f.static)

	v.execute(f.code)

	f.execCount++

	// keep largest global buffer
	if cap(global) > cap(f.global) {
		f.global = global[:0]
	} else if len(f.global) > 0 {
		f.global = f.global[:0]
	}

	// check for global data to be saved for next program execution
	globalSize := binary.LittleEndian.Uint32(vg[0x30:])
	if globalSize > 0 {
		if globalSize > vmGlobalSize-vmFixedGlobalSize {
			globalSize = vmGlobalSize - vmFixedGlobalSize
		}
		if cap(f.global) < int(globalSize) {
			f.global = make([]byte, globalSize)
		} else {
			f.global = f.global[:globalSize]
		}
		copy(f.global, vg[vmFixedGlobalSize:])
	}

	// find program output
	length := binary.LittleEndian.Uint32(vg[0x1c:]) & vmMask
	start := binary.LittleEndian.Uint32(vg[0x20:]) & vmMask
	if start+length > vmSize {
		// TODO: error
		start = 0
		length = 0
	}
	if start != 0 && cap(v.m) > cap(buf) {
		// Initial buffer was to small for vm.
		// Copy output to beginning of vm memory so that decodeReader
		// will re-use the newly allocated vm memory and we will not
		// have to reallocate again next time.
		copy(v.m, v.m[start:start+length])
		start = 0
	}
	return v.m[start : start+length], nil
}

// getV3Filter returns a V3 filter function from a code byte slice.
func getV3Filter(code []byte) (v3Filter, error) {
	// check if filter is a known standard filter
	c := crc32.ChecksumIEEE(code)
	for _, f := range standardV3Filters {
		if f.crc == c && f.len == len(code) {
			return f.f, nil
		}
	}

	// create new vm filter
	f := new(vmFilter)
	r := newRarBitReader(bytes.NewReader(code[1:])) // skip first xor byte check

	// read static data
	n, err := r.readBits(1)
	if err != nil {
		return nil, err
	}
	if n > 0 {
		m, err := r.readUint32()
		if err != nil {
			return nil, err
		}
		f.static = make([]byte, m+1)
		err = r.readFull(f.static)
		if err != nil {
			return nil, err
		}
	}

	f.code, err = readCommands(r)
	if err == io.EOF {
		err = nil
	}

	return f.execute, err
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"strings"

	"github.com/abadojack/whatlanggo"
	"github.com/donomii/throfflib"
)

//_ "net/http/pprof"

var lang = "en"

func main() {
	go func() {
		//log.Println(http.ListenAndServe("localhost:6060", nil))
	}()
	t := throfflib.MakeEngine()
	t = throfflib.LoadGraphics(t)
	//t = throfflib.LoadAudio(t)
	strs := os.Args[1:]
	//log.Printf("Evaluating %v\n", strs)
	for _, arg := range strs {
		if whatlanggo.Jpn == whatlanggo.Detect(arg).Lang {
			lang = "jp"
			//log.Println("Japanese detected")
		}
	}
	//t = t.RunFile("bootstrapgo.lib")
	t = t.RunString(throfflib.BootStrapString(), "Internal Bootstrap")

	if len(strs) == 0 {
		t = t.RunString("PRINTLN [ Welcome to the THROFF REPL v0.1.  Type HELP for help. ]", "repl")
		throfflib.Repl(t)
	} else {
		throfflib.PrintWarnings = false
		if lang == "jp" {
			throfflib.BraceMode = "forth"
			strs = strings.Split(strs[0], "　")
		}

		t = t.RunString("SPACE", "Command line evaluator") //We print the top of the stack after the calculation.  If the calculation returns nothing, we don't want to print "Stack empty"

		tokens := throfflib.StringsToTokens(strs)
		t.LoadTokens(tokens)

		t = t.Run()
		t.RunString("PRINTLN", "replprint")
	}
}
<commit_msg>Support Japanese in the REPL<commit_after>package main

import (
	"os"
	"strings"

	"github.com/abadojack/whatlanggo"
	"github.com/donomii/throfflib"
)

//_ "net/http/pprof"

var lang = "en"

func main() {
	go func() {
		//log.Println(http.ListenAndServe("localhost:6060", nil))
	}()
	t := throfflib.MakeEngine()
	t = throfflib.LoadGraphics(t)
	//t = throfflib.LoadAudio(t)
	strs := os.Args[1:]
	//log.Printf("Evaluating %v\n", strs)
	for _, arg := range strs {
		if whatlanggo.Jpn == whatlanggo.Detect(arg).Lang {
			lang = "jp"
			//log.Println("Japanese detected")
		}
	}
	//t = t.RunFile("bootstrapgo.lib")
	t = t.RunString(throfflib.BootStrapString(), "Internal Bootstrap")

	if len(strs) == 0 {
		t = t.RunString("PRINTLN [ Welcome to THROFF  v0.1.  Type HELP for help. ]", "repl")
		t = t.RunString(" [ \nTHROFF v0.1.  Type HELP for help. ]", "repl")
		throfflib.Repl(t)
	} else {
		throfflib.PrintWarnings = false
		if lang == "jp" {
			throfflib.BraceMode = "forth"
			strs = strings.Split(strs[0], "　")
		}

		t = t.RunString("SPACE", "Command line evaluator") //We print the top of the stack after the calculation.  If the calculation returns nothing, we don't want to print "Stack empty"

		tokens := throfflib.StringsToTokens(strs)
		t.LoadTokens(tokens)

		t = t.Run()
		t.RunString("PRINTLN", "replprint")
	}
}
<|endoftext|>


<commit_before>package knx

type reaper <-chan struct{}

type scythe func()

func makeReaper() (reaper, scythe) {
	r := make(chan struct{}, 1)

	s := func () {
		select {
			case r <- struct{}{}:
			default:
		}
	}

	return r, s
}
<commit_msg>Remove reaper<commit_after><|endoftext|>


<commit_before>// Copyright 2016 Stratumn SAS. All rights reserved.
// Use of this source code is governed by the license
// that can be found in the LICENSE file.

// Package merkle contains types and functions to create and work with Merkle trees.
package merkle

import (
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
)

const (
	// HashByteLen is the length of a hash or leaf measured in bytes.
	HashByteLen = sha256.Size
)

// Hash is a binary encoded 32-bit hash.
type Hash [HashByteLen]byte

// MarshalJSON implements encoding/json.Marshaler.MarshalJSON.
func (h *Hash) MarshalJSON() ([]byte, error) {
	return json.Marshal(hex.EncodeToString(h[:]))
}

// UnmarshalJSON implements encoding/json.Unarshaler.UnmarshalJSON.
func (h *Hash) UnmarshalJSON(data []byte) error {
	var s string
	if err := json.Unmarshal(data, &s); err != nil {
		return err
	}

	if _, err := hex.Decode(h[:], []byte(s)); err != nil {
		return err
	}

	return nil
}

// HashTriplet contains a left, right, and parent hash.
type HashTriplet struct {
	Left   Hash `json:"left"`
	Right  Hash `json:"right"`
	Parent Hash `json:"parent"`
}

// Path contains the necessary hashes to go from a leaf to a Merkle root.
type Path []HashTriplet

// Tree must be implemented by Merkle tree implementations.
type Tree interface {
	// NumLeaves returns the number of leaves.
	NumLeaves() int

	// Leaf returns the Merkle root.
	Root() Hash

	// Leaf returns the leaf at the specified index.
	Leaf(index int) Hash

	// Path returns the path of a leaf to the Merkle root.
	Path(index int) Path
}
<commit_msg>merkle: Typo<commit_after>// Copyright 2016 Stratumn SAS. All rights reserved.
// Use of this source code is governed by the license
// that can be found in the LICENSE file.

// Package merkle contains types and functions to create and work with Merkle trees.
package merkle

import (
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
)

const (
	// HashByteLen is the length of a hash or leaf measured in bytes.
	HashByteLen = sha256.Size
)

// Hash is a binary encoded 32-bit hash.
type Hash [HashByteLen]byte

// MarshalJSON implements encoding/json.Marshaler.MarshalJSON.
func (h *Hash) MarshalJSON() ([]byte, error) {
	return json.Marshal(hex.EncodeToString(h[:]))
}

// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON.
func (h *Hash) UnmarshalJSON(data []byte) error {
	var s string
	if err := json.Unmarshal(data, &s); err != nil {
		return err
	}

	if _, err := hex.Decode(h[:], []byte(s)); err != nil {
		return err
	}

	return nil
}

// HashTriplet contains a left, right, and parent hash.
type HashTriplet struct {
	Left   Hash `json:"left"`
	Right  Hash `json:"right"`
	Parent Hash `json:"parent"`
}

// Path contains the necessary hashes to go from a leaf to a Merkle root.
type Path []HashTriplet

// Tree must be implemented by Merkle tree implementations.
type Tree interface {
	// NumLeaves returns the number of leaves.
	NumLeaves() int

	// Leaf returns the Merkle root.
	Root() Hash

	// Leaf returns the leaf at the specified index.
	Leaf(index int) Hash

	// Path returns the path of a leaf to the Merkle root.
	Path(index int) Path
}
<|endoftext|>