<commit_before>// Copyright (C) 2017 Google Inc.
//
// 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 compiler

import (
	"github.com/google/gapid/core/codegen"
	"github.com/google/gapid/gapil/semantic"
)

func (c *C) doCast(s *S, dstTy, srcTy semantic.Type, v *codegen.Value) *codegen.Value {
	srcPtrTy, srcIsPtr := srcTy.(*semantic.Pointer)
	// dstPtrTy, dstIsPtr := dstTy.(*semantic.Pointer)
	srcSliceTy, srcIsSlice := srcTy.(*semantic.Slice)
	dstSliceTy, dstIsSlice := dstTy.(*semantic.Slice)
	srcIsString := srcTy == semantic.StringType
	dstIsString := dstTy == semantic.StringType

	switch {
	case srcIsPtr && srcPtrTy.To == semantic.CharType && dstIsString:
		// char* -> string
		slicePtr := s.Local("slice", c.T.Sli)
		s.Call(c.callbacks.cstringToSlice, s.Ctx, v, slicePtr)
		slice := slicePtr.Load()
		c.plugins.foreach(func(p OnReadListener) { p.OnRead(s, slice, srcPtrTy.Slice) })
		str := s.Call(c.callbacks.sliceToString, s.Ctx, slicePtr)
		c.release(s, slice, slicePrototype)
		c.deferRelease(s, str, semantic.StringType)
		return str
	case srcIsSlice && srcSliceTy.To == semantic.CharType && dstIsString:
		// char[] -> string
		slicePtr := s.LocalInit("slice", v)
		c.plugins.foreach(func(p OnReadListener) { p.OnRead(s, v, srcSliceTy) })
		return s.Call(c.callbacks.sliceToString, s.Ctx, slicePtr)
	case srcIsString && dstIsSlice && dstSliceTy.To == semantic.CharType:
		// string -> char[]
		slicePtr := s.Local("slice", c.T.Sli)
		s.Call(c.callbacks.stringToSlice, s.Ctx, v, slicePtr)
		return slicePtr.Load()
	case srcIsSlice && dstIsSlice:
		// T[] -> T[]
		root := v.Extract(SliceRoot)
		base := v.Extract(SliceBase)
		size := v.Extract(SliceSize)
		pool := v.Extract(SlicePool)
		count := s.Div(size, s.SizeOf(c.T.Capture(srcSliceTy.To)))
		size = s.Mul(count, s.SizeOf(c.T.Capture(dstSliceTy.To)))
		return c.buildSlice(s, root, base, size, count, pool)
	default:
		return v.Cast(c.T.Target(dstTy)) // TODO: capture vs memory.
	}
}

func (c *C) castTargetToCapture(s *S, ty semantic.Type, v *codegen.Value) *codegen.Value {
	ty = semantic.Underlying(ty)
	dstTy, srcTy := c.T.Capture(ty), c.T.Target(ty)
	if srcTy != v.Type() {
		fail("castTargetToCapture called with a value that is not of the target type")
	}
	if dstTy == srcTy {
		return v
	}

	_, isPtr := ty.(*semantic.Pointer)
	_, isClass := ty.(*semantic.Class)
	switch {
	case isPtr: // pointer -> uint64
		return v.Cast(dstTy)
	case isClass:
		if fn, ok := c.T.targetToCapture[ty]; ok {
			tmpTarget := s.Local("cast_target_"+ty.Name(), dstTy)
			tmpSource := s.LocalInit("cast_source_"+ty.Name(), v)
			s.Call(fn, s.Ctx, tmpSource, tmpTarget)
			return tmpTarget.Load()
		}
		fail("castTargetToCapture() cannot handle type %v (%v -> %v)", ty.Name(), srcTy.TypeName(), dstTy.TypeName())
		return nil
	case ty == semantic.IntType, ty == semantic.SizeType:
		return v.Cast(dstTy)
	default:
		fail("castTargetToCapture() cannot handle type %v (%v -> %v)", ty.Name(), srcTy.TypeName(), dstTy.TypeName())
		return nil
	}
}

func (c *C) castCaptureToTarget(s *S, ty semantic.Type, v *codegen.Value) *codegen.Value {
	ty = semantic.Underlying(ty)
	dstTy, srcTy := c.T.Target(ty), c.T.Capture(ty)
	if srcTy != v.Type() {
		fail("castCaptureToTarget called with a value that is not of the capture type %+v, %+v", srcTy, v.Type())
	}
	if dstTy == srcTy {
		return v
	}

	_, isPtr := ty.(*semantic.Pointer)
	_, isClass := ty.(*semantic.Class)
	switch {
	case isPtr: // uint64 -> pointer
		return v.Cast(dstTy)
	case isClass:
		if fn, ok := c.T.captureToTarget[ty]; ok {
			tmpTarget := s.Local("cast_target_"+ty.Name(), dstTy)
			tmpSource := s.LocalInit("cast_source_"+ty.Name(), v)
			s.Call(fn, s.Ctx, tmpSource, tmpTarget)
			return tmpTarget.Load()
		}
		fail("castCaptureToTarget() cannot handle type %v (%v -> %v)", ty.Name(), srcTy.TypeName(), dstTy.TypeName())
		return nil
	case ty == semantic.IntType, ty == semantic.SizeType:
		return v.Cast(dstTy)
	default:
		fail("castCaptureToTarget() cannot handle type %v (%v -> %v)", ty.Name(), srcTy.TypeName(), dstTy.TypeName())
		return nil
	}
}
<commit_msg>gapil/compiler: Handle T<->S casting of static arrays<commit_after>// Copyright (C) 2017 Google Inc.
//
// 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 compiler

import (
	"github.com/google/gapid/core/codegen"
	"github.com/google/gapid/gapil/semantic"
)

func (c *C) doCast(s *S, dstTy, srcTy semantic.Type, v *codegen.Value) *codegen.Value {
	srcPtrTy, srcIsPtr := srcTy.(*semantic.Pointer)
	// dstPtrTy, dstIsPtr := dstTy.(*semantic.Pointer)
	srcSliceTy, srcIsSlice := srcTy.(*semantic.Slice)
	dstSliceTy, dstIsSlice := dstTy.(*semantic.Slice)
	srcIsString := srcTy == semantic.StringType
	dstIsString := dstTy == semantic.StringType

	switch {
	case srcIsPtr && srcPtrTy.To == semantic.CharType && dstIsString:
		// char* -> string
		slicePtr := s.Local("slice", c.T.Sli)
		s.Call(c.callbacks.cstringToSlice, s.Ctx, v, slicePtr)
		slice := slicePtr.Load()
		c.plugins.foreach(func(p OnReadListener) { p.OnRead(s, slice, srcPtrTy.Slice) })
		str := s.Call(c.callbacks.sliceToString, s.Ctx, slicePtr)
		c.release(s, slice, slicePrototype)
		c.deferRelease(s, str, semantic.StringType)
		return str
	case srcIsSlice && srcSliceTy.To == semantic.CharType && dstIsString:
		// char[] -> string
		slicePtr := s.LocalInit("slice", v)
		c.plugins.foreach(func(p OnReadListener) { p.OnRead(s, v, srcSliceTy) })
		return s.Call(c.callbacks.sliceToString, s.Ctx, slicePtr)
	case srcIsString && dstIsSlice && dstSliceTy.To == semantic.CharType:
		// string -> char[]
		slicePtr := s.Local("slice", c.T.Sli)
		s.Call(c.callbacks.stringToSlice, s.Ctx, v, slicePtr)
		return slicePtr.Load()
	case srcIsSlice && dstIsSlice:
		// T[] -> T[]
		root := v.Extract(SliceRoot)
		base := v.Extract(SliceBase)
		size := v.Extract(SliceSize)
		pool := v.Extract(SlicePool)
		count := s.Div(size, s.SizeOf(c.T.Capture(srcSliceTy.To)))
		size = s.Mul(count, s.SizeOf(c.T.Capture(dstSliceTy.To)))
		return c.buildSlice(s, root, base, size, count, pool)
	default:
		return v.Cast(c.T.Target(dstTy)) // TODO: capture vs memory.
	}
}

func (c *C) castTargetToCapture(s *S, ty semantic.Type, v *codegen.Value) *codegen.Value {
	ty = semantic.Underlying(ty)
	dstTy, srcTy := c.T.Capture(ty), c.T.Target(ty)
	if srcTy != v.Type() {
		fail("castTargetToCapture called with a value that is not of the target type")
	}
	if dstTy == srcTy {
		return v
	}

	switch ty := ty.(type) {
	case *semantic.Pointer: // pointer -> uint64
		return v.Cast(dstTy)
	case *semantic.Class:
		if fn, ok := c.T.targetToCapture[ty]; ok {
			tmpTarget := s.Local("cast_target_"+ty.Name(), dstTy)
			tmpSource := s.LocalInit("cast_source_"+ty.Name(), v)
			s.Call(fn, s.Ctx, tmpSource, tmpTarget)
			return tmpTarget.Load()
		}
		fail("castTargetToCapture() cannot handle type %v (%v -> %v)", ty.Name(), srcTy.TypeName(), dstTy.TypeName())
		return nil
	case *semantic.StaticArray:
		src, dst := s.LocalInit("src", v), s.Local("dst", dstTy)
		s.ForN(s.Scalar(ty.Size), func(s *S, it *codegen.Value) *codegen.Value {
			src := src.Index(0, it)
			dst := dst.Index(0, it)
			dst.Store(c.castTargetToCapture(s, ty.ValueType, src.Load()))
			return nil
		})
		return dst.Load()
	default:
		if ty == semantic.IntType || ty == semantic.SizeType {
			return v.Cast(dstTy)
		}
		fail("castTargetToCapture() cannot handle type %v (%v -> %v)", ty.Name(), srcTy.TypeName(), dstTy.TypeName())
		return nil
	}
}

func (c *C) castCaptureToTarget(s *S, ty semantic.Type, v *codegen.Value) *codegen.Value {
	ty = semantic.Underlying(ty)
	dstTy, srcTy := c.T.Target(ty), c.T.Capture(ty)
	if srcTy != v.Type() {
		fail("castCaptureToTarget called with a value that is not of the capture type %+v, %+v", srcTy, v.Type())
	}
	if dstTy == srcTy {
		return v
	}

	switch ty := ty.(type) {
	case *semantic.Pointer: // uint64 -> pointer
		return v.Cast(dstTy)
	case *semantic.Class:
		if fn, ok := c.T.captureToTarget[ty]; ok {
			tmpTarget := s.Local("cast_target_"+ty.Name(), dstTy)
			tmpSource := s.LocalInit("cast_source_"+ty.Name(), v)
			s.Call(fn, s.Ctx, tmpSource, tmpTarget)
			return tmpTarget.Load()
		}
		fail("castCaptureToTarget() cannot handle type %v (%v -> %v)", ty.Name(), srcTy.TypeName(), dstTy.TypeName())
		return nil
	case *semantic.StaticArray:
		src, dst := s.LocalInit("src", v), s.Local("dst", dstTy)
		s.ForN(s.Scalar(ty.Size), func(s *S, it *codegen.Value) *codegen.Value {
			src := src.Index(0, it)
			dst := dst.Index(0, it)
			dst.Store(c.castCaptureToTarget(s, ty.ValueType, src.Load()))
			return nil
		})
		return dst.Load()
	default:
		if ty == semantic.IntType || ty == semantic.SizeType {
			return v.Cast(dstTy)
		}
		fail("castCaptureToTarget() cannot handle type %v (%v -> %v)", ty.Name(), srcTy.TypeName(), dstTy.TypeName())
		return nil
	}
}
<|endoftext|>


<commit_before>// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// 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.

// +build darwin linux

package shell

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"os/exec"
	"os/signal"
	"strconv"
	"syscall"
	"time"

	"../cause"
)

func init() {
	// As we are going to be running a number of tests concurrently, we need to
	// limit the amount of virtual memory each test uses, otherwise memory
	// hungry tests can bring the whole system down into a swapping apocalypse.
	//
	// Linux has the setrlimit() function to limit a process (and child's)
	// virtual memory usage - but we cannot call this from the regres process
	// as this process may need more memory than the limit allows.
	//
	// Unfortunately golang has no native support for setting rlimits for child
	// processes (https://github.com/golang/go/issues/6603), so we instead wrap
	// the exec to the test executable with another child regres process using a
	// special --exec mode:
	//
	// [regres] -> [regres --exec <test-exe N args...>] -> [test-exe]
	//               ^^^^
	//          (calls rlimit() with memory limit of N bytes)

	if len(os.Args) > 3 && os.Args[1] == "--exec" {
		exe := os.Args[2]
		limit, err := strconv.ParseUint(os.Args[3], 10, 64)
		if err != nil {
			log.Fatalf("Expected memory limit as 3rd argument. %v\n", err)
		}
		if limit > 0 {
			if err := syscall.Setrlimit(syscall.RLIMIT_AS, &syscall.Rlimit{Cur: limit, Max: limit}); err != nil {
				log.Fatalln(cause.Wrap(err, "Setrlimit").Error())
			}
		}
		cmd := exec.Command(exe, os.Args[4:]...)
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Start(); err != nil {
			os.Stderr.WriteString(err.Error())
			os.Exit(1)
		}
		// Forward signals to the child process
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)
		go func() {
			for sig := range c {
				cmd.Process.Signal(sig)
			}
		}()
		cmd.Wait()
		close(c)
		os.Exit(cmd.ProcessState.ExitCode())
	}
}

// Exec runs the executable exe with the given arguments, in the working
// directory wd, with the custom environment flags.
// If the process does not finish within timeout a errTimeout will be returned.
func Exec(timeout time.Duration, exe, wd string, env []string, args ...string) ([]byte, error) {
	// Shell via regres: --exec N <exe> <args...>
	// See main() for details.
	args = append([]string{"--exec", exe, fmt.Sprintf("%v", MaxProcMemory)}, args...)
	b := bytes.Buffer{}
	c := exec.Command(os.Args[0], args...)
	c.Dir = wd
	c.Env = env
	c.Stdout = &b
	c.Stderr = &b

	if err := c.Start(); err != nil {
		return nil, err
	}

	res := make(chan error)
	go func() { res <- c.Wait() }()

	select {
	case <-time.NewTimer(timeout).C:
		c.Process.Signal(syscall.SIGINT)
		time.Sleep(time.Second * 3)
		if !c.ProcessState.Exited() {
			log.Printf("Process %v still has not exited, killing\n", c.Process.Pid)
			syscall.Kill(-c.Process.Pid, syscall.SIGKILL)
		}
		return b.Bytes(), ErrTimeout{exe, timeout}
	case err := <-res:
		return b.Bytes(), err
	}
}
<commit_msg>Regres: Avoid dereferencing a nil on process timeout.<commit_after>// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// 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.

// +build darwin linux

package shell

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"os/exec"
	"os/signal"
	"strconv"
	"syscall"
	"time"

	"../cause"
)

func init() {
	// As we are going to be running a number of tests concurrently, we need to
	// limit the amount of virtual memory each test uses, otherwise memory
	// hungry tests can bring the whole system down into a swapping apocalypse.
	//
	// Linux has the setrlimit() function to limit a process (and child's)
	// virtual memory usage - but we cannot call this from the regres process
	// as this process may need more memory than the limit allows.
	//
	// Unfortunately golang has no native support for setting rlimits for child
	// processes (https://github.com/golang/go/issues/6603), so we instead wrap
	// the exec to the test executable with another child regres process using a
	// special --exec mode:
	//
	// [regres] -> [regres --exec <test-exe N args...>] -> [test-exe]
	//               ^^^^
	//          (calls rlimit() with memory limit of N bytes)

	if len(os.Args) > 3 && os.Args[1] == "--exec" {
		exe := os.Args[2]
		limit, err := strconv.ParseUint(os.Args[3], 10, 64)
		if err != nil {
			log.Fatalf("Expected memory limit as 3rd argument. %v\n", err)
		}
		if limit > 0 {
			if err := syscall.Setrlimit(syscall.RLIMIT_AS, &syscall.Rlimit{Cur: limit, Max: limit}); err != nil {
				log.Fatalln(cause.Wrap(err, "Setrlimit").Error())
			}
		}
		cmd := exec.Command(exe, os.Args[4:]...)
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Start(); err != nil {
			os.Stderr.WriteString(err.Error())
			os.Exit(1)
		}
		// Forward signals to the child process
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)
		go func() {
			for sig := range c {
				cmd.Process.Signal(sig)
			}
		}()
		cmd.Wait()
		close(c)
		os.Exit(cmd.ProcessState.ExitCode())
	}
}

// Exec runs the executable exe with the given arguments, in the working
// directory wd, with the custom environment flags.
// If the process does not finish within timeout a errTimeout will be returned.
func Exec(timeout time.Duration, exe, wd string, env []string, args ...string) ([]byte, error) {
	// Shell via regres: --exec N <exe> <args...>
	// See main() for details.
	args = append([]string{"--exec", exe, fmt.Sprintf("%v", MaxProcMemory)}, args...)
	b := bytes.Buffer{}
	c := exec.Command(os.Args[0], args...)
	c.Dir = wd
	c.Env = env
	c.Stdout = &b
	c.Stderr = &b

	if err := c.Start(); err != nil {
		return nil, err
	}

	res := make(chan error)
	go func() { res <- c.Wait() }()

	select {
	case <-time.NewTimer(timeout).C:
		c.Process.Signal(syscall.SIGINT)
		time.Sleep(time.Second * 3)
		if c.ProcessState == nil || !c.ProcessState.Exited() {
			log.Printf("Process %v still has not exited, killing\n", c.Process.Pid)
			syscall.Kill(-c.Process.Pid, syscall.SIGKILL)
		}
		return b.Bytes(), ErrTimeout{exe, timeout}
	case err := <-res:
		return b.Bytes(), err
	}
}
<|endoftext|>


<commit_before>/**
 *  Copyright 2014 Paul Querna
 *
 *  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 reports

import (
	"fmt"
	"github.com/pquerna/hurl/common"
	"github.com/rcrowley/go-metrics"
	"time"
)

func init() {
	AddReporter(&HTTPResponseSize{})
	AddReporter(&HTTPResponseTime{})
}

type HTTPReport struct{}

func (ht *HTTPReport) Interest(ui common.UI, taskType string) bool {
	if taskType == "http" {
		return true
	}
	return false
}

type HTTPResponseSize struct {
	HTTPReport
	h metrics.Histogram
}

type HTTPResponseTime struct {
	HTTPReport
	h metrics.Histogram
}

func (hrs *HTTPResponseSize) ReadResults(rr *common.ResultArchiveReader) {
	hrs.h = metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015))

	for rr.Scan() {
		rv := rr.Entry()
		hrs.h.Update(int64(rv.Metrics["BodyLength"]))
	}
}

func (hrs *HTTPResponseSize) ConsoleOutput() {
	fmt.Printf("Response Size Average: %02f\n", hrs.h.Mean())
	fmt.Printf("Response Size Variance: %02f\n", hrs.h.Variance())
}

func (hrs *HTTPResponseTime) ReadResults(rr *common.ResultArchiveReader) {
	hrs.h = metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015))

	for rr.Scan() {
		rv := rr.Entry()
		hrs.h.Update(int64(rv.Duration))
	}
}

func (hrs *HTTPResponseTime) ConsoleOutput() {
	fmt.Printf("Response Time Average: %v\n", time.Duration(hrs.h.Mean()))
	fmt.Printf("Response Time Variance: %02f\n", hrs.h.Variance())
}
<commit_msg>only show percentiles on response size if it varied, and improve response time display<commit_after>/**
 *  Copyright 2014 Paul Querna
 *
 *  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 reports

import (
	"fmt"
	"github.com/pquerna/hurl/common"
	"github.com/rcrowley/go-metrics"
	"time"
)

func init() {
	AddReporter(&HTTPResponseSize{})
	AddReporter(&HTTPResponseTime{})
}

type HTTPReport struct{}

func (ht *HTTPReport) Interest(ui common.UI, taskType string) bool {
	if taskType == "http" {
		return true
	}
	return false
}

type HTTPResponseSize struct {
	HTTPReport
	h metrics.Histogram
}

type HTTPResponseTime struct {
	HTTPReport
	h metrics.Histogram
}

func (hrs *HTTPResponseSize) ReadResults(rr *common.ResultArchiveReader) {
	hrs.h = metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015))

	for rr.Scan() {
		rv := rr.Entry()
		hrs.h.Update(int64(rv.Metrics["BodyLength"]))
	}
}

func (hrs *HTTPResponseSize) ConsoleOutput() {
	if hrs.h.Min() != hrs.h.Max() {
		fmt.Printf("Response Size:\n")
		fmt.Printf("				Mean		%v\n", hrs.h.Mean())
		fmt.Printf("				90%%		%v\n", hrs.h.Percentile(0.90))
		fmt.Printf("				95%%		%v\n", hrs.h.Percentile(0.95))
		fmt.Printf("				99%%		%v\n", hrs.h.Percentile(0.99))
	} else {
		fmt.Printf("Response Size: %d\n", int(hrs.h.Max()))
	}
}

func (hrs *HTTPResponseTime) ReadResults(rr *common.ResultArchiveReader) {
	hrs.h = metrics.NewHistogram(metrics.NewExpDecaySample(1028, 0.015))

	for rr.Scan() {
		rv := rr.Entry()
		hrs.h.Update(int64(rv.Duration))
	}
}

func (hrt *HTTPResponseTime) ConsoleOutput() {
	fmt.Printf("Response Time:\n")
	fmt.Printf("				Min 		%v\n", time.Duration(hrt.h.Min()))
	fmt.Printf("				Mean		%v\n", time.Duration(hrt.h.Mean()))
	fmt.Printf("				90%%		%v\n", time.Duration(hrt.h.Percentile(0.90)))
	fmt.Printf("				95%%		%v\n", time.Duration(hrt.h.Percentile(0.95)))
	fmt.Printf("				99%%		%v\n", time.Duration(hrt.h.Percentile(0.99)))
	fmt.Printf("				Max 		%v\n", time.Duration(hrt.h.Max()))
}
<|endoftext|>


<commit_before>package intercept

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"errors"
	"github.com/nbio/st"
	"io/ioutil"
	"net/http"
	"strings"
	"testing"
)

var errRead = errors.New("read error")

type errorReader struct{}

func (r *errorReader) Read(p []byte) (int, error) {
	return 0, errRead
}

type user struct {
	XMLName xml.Name `xml:"Person"`
	Name    string
}

func TestNewRequestModifier(t *testing.T) {
	h := http.Header{}
	h.Set("foo", "bar")
	req := &http.Request{Header: h}
	modifier := NewRequestModifier(req)
	st.Expect(t, modifier.Request, req)
	st.Expect(t, modifier.Header, h)
}

func TestReadString(t *testing.T) {
	bodyStr := `{"name":"Rick"}`
	strReader := strings.NewReader(bodyStr)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	str, err := modifier.ReadString()
	st.Expect(t, err, nil)
	st.Expect(t, str, bodyStr)
}

func TestReadStringError(t *testing.T) {
	body := ioutil.NopCloser(&errorReader{})
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	str, err := modifier.ReadString()
	st.Expect(t, err, errRead)
	st.Expect(t, str, "")
}

func TestReadBytes(t *testing.T) {
	bodyBytes := []byte(`{"name":"Rick"}`)
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	str, err := modifier.ReadBytes()
	st.Expect(t, err, nil)
	st.Expect(t, str, bodyBytes)
}

func TestReadBytesError(t *testing.T) {
	body := ioutil.NopCloser(&errorReader{})
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	buf, err := modifier.ReadBytes()
	st.Expect(t, err, errRead)
	st.Expect(t, len(buf), 0)
}

func TestDecodeJSON(t *testing.T) {
	bodyBytes := []byte(`{"name":"Rick"}`)
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeJSON(&u)
	st.Expect(t, err, nil)
	st.Expect(t, u.Name, "Rick")
}

func TestDecodeJSONErrorFromReadBytes(t *testing.T) {
	body := ioutil.NopCloser(&errorReader{})
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeJSON(&u)
	st.Expect(t, err, errRead)
	st.Expect(t, u.Name, "")
}

func TestDecodeJSONEOF(t *testing.T) {
	bodyBytes := []byte("")
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeJSON(&u)
	st.Expect(t, err, nil)
	st.Expect(t, u.Name, "")
}

func TestDecodeJSONErrorFromDecode(t *testing.T) {
	bodyBytes := []byte(`/`)
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeJSON(&u)
	_, ok := (err).(*json.SyntaxError)
	st.Expect(t, ok, true)
	st.Expect(t, err.Error(), "invalid character '/' looking for beginning of value")
	st.Expect(t, u.Name, "")
}

func TestDecodeXML(t *testing.T) {
	bodyBytes := []byte(`<Person><Name>Rick</Name></Person>`)
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeXML(&u, nil)
	st.Expect(t, err, nil)
	st.Expect(t, u.Name, "Rick")
}

func TestDecodeXMLErrorFromReadBytes(t *testing.T) {
	body := ioutil.NopCloser(&errorReader{})
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeXML(&u, nil)
	st.Expect(t, err, errRead)
	st.Expect(t, u.Name, "")
}

func TestDecodeXMLErrorFromDecode(t *testing.T) {
	bodyBytes := []byte(`]]>`)
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeXML(&u, nil)
	_, ok := (err).(*xml.SyntaxError)
	st.Expect(t, ok, true)
	st.Expect(t, err.Error(), "XML syntax error on line 1: unescaped ]]> not in CDATA section")
	st.Expect(t, u.Name, "")
}

func TestDecodeXMLEOF(t *testing.T) {
	bodyBytes := []byte("")
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeXML(&u, nil)
	st.Expect(t, err, nil)
	st.Expect(t, u.Name, "")
}
<commit_msg>feat(test): Add test for Bytes<commit_after>package intercept

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"errors"
	"github.com/nbio/st"
	"io/ioutil"
	"net/http"
	"strings"
	"testing"
)

var errRead = errors.New("read error")

type errorReader struct{}

func (r *errorReader) Read(p []byte) (int, error) {
	return 0, errRead
}

type user struct {
	XMLName xml.Name `xml:"Person"`
	Name    string
}

func TestNewRequestModifier(t *testing.T) {
	h := http.Header{}
	h.Set("foo", "bar")
	req := &http.Request{Header: h}
	modifier := NewRequestModifier(req)
	st.Expect(t, modifier.Request, req)
	st.Expect(t, modifier.Header, h)
}

func TestReadString(t *testing.T) {
	bodyStr := `{"name":"Rick"}`
	strReader := strings.NewReader(bodyStr)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	str, err := modifier.ReadString()
	st.Expect(t, err, nil)
	st.Expect(t, str, bodyStr)
}

func TestReadStringError(t *testing.T) {
	body := ioutil.NopCloser(&errorReader{})
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	str, err := modifier.ReadString()
	st.Expect(t, err, errRead)
	st.Expect(t, str, "")
}

func TestReadBytes(t *testing.T) {
	bodyBytes := []byte(`{"name":"Rick"}`)
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	str, err := modifier.ReadBytes()
	st.Expect(t, err, nil)
	st.Expect(t, str, bodyBytes)
}

func TestReadBytesError(t *testing.T) {
	body := ioutil.NopCloser(&errorReader{})
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	buf, err := modifier.ReadBytes()
	st.Expect(t, err, errRead)
	st.Expect(t, len(buf), 0)
}

func TestDecodeJSON(t *testing.T) {
	bodyBytes := []byte(`{"name":"Rick"}`)
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeJSON(&u)
	st.Expect(t, err, nil)
	st.Expect(t, u.Name, "Rick")
}

func TestDecodeJSONErrorFromReadBytes(t *testing.T) {
	body := ioutil.NopCloser(&errorReader{})
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeJSON(&u)
	st.Expect(t, err, errRead)
	st.Expect(t, u.Name, "")
}

func TestDecodeJSONEOF(t *testing.T) {
	bodyBytes := []byte("")
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeJSON(&u)
	st.Expect(t, err, nil)
	st.Expect(t, u.Name, "")
}

func TestDecodeJSONErrorFromDecode(t *testing.T) {
	bodyBytes := []byte(`/`)
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeJSON(&u)
	_, ok := (err).(*json.SyntaxError)
	st.Expect(t, ok, true)
	st.Expect(t, err.Error(), "invalid character '/' looking for beginning of value")
	st.Expect(t, u.Name, "")
}

func TestDecodeXML(t *testing.T) {
	bodyBytes := []byte(`<Person><Name>Rick</Name></Person>`)
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeXML(&u, nil)
	st.Expect(t, err, nil)
	st.Expect(t, u.Name, "Rick")
}

func TestDecodeXMLErrorFromReadBytes(t *testing.T) {
	body := ioutil.NopCloser(&errorReader{})
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeXML(&u, nil)
	st.Expect(t, err, errRead)
	st.Expect(t, u.Name, "")
}

func TestDecodeXMLErrorFromDecode(t *testing.T) {
	bodyBytes := []byte(`]]>`)
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeXML(&u, nil)
	_, ok := (err).(*xml.SyntaxError)
	st.Expect(t, ok, true)
	st.Expect(t, err.Error(), "XML syntax error on line 1: unescaped ]]> not in CDATA section")
	st.Expect(t, u.Name, "")
}

func TestDecodeXMLEOF(t *testing.T) {
	bodyBytes := []byte("")
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	u := user{}
	err := modifier.DecodeXML(&u, nil)
	st.Expect(t, err, nil)
	st.Expect(t, u.Name, "")
}

func TestBytes(t *testing.T) {
	bodyBytes := []byte("")
	strReader := bytes.NewBuffer(bodyBytes)
	body := ioutil.NopCloser(strReader)
	req := &http.Request{Header: http.Header{}, Body: body}
	modifier := NewRequestModifier(req)
	modifier.Bytes([]byte("hello"))
	modifiedBody, err := ioutil.ReadAll(req.Body)
	st.Expect(t, err, nil)
	st.Expect(t, modifiedBody, []byte("hello"))
}
<|endoftext|>


<commit_before>package geos

/*
#cgo LDFLAGS: -lgeos_c
#include "geos_c.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>

extern void goLogString(char *msg);
extern void goSendQueryResult(size_t, void *);

void debug_wrap(const char *fmt, ...) {
	va_list a_list;
    va_start(a_list, fmt);

	char buf[100];
	vsnprintf(buf, sizeof(buf), fmt, a_list);
	va_end(a_list);
	goLogString((char *)&buf);
}

GEOSContextHandle_t initGEOS_r_debug() {
	return initGEOS_r(debug_wrap, debug_wrap);
}

void initGEOS_debug() {
    return initGEOS(debug_wrap, debug_wrap);
}

// wrap goIndexSendQueryResult
void IndexQuerySendCallback(void *item, void *userdata) {
    goIndexSendQueryResult((size_t)item, userdata);
}

void IndexAdd(
    GEOSContextHandle_t handle,
    GEOSSTRtree *tree,
    const GEOSGeometry *g,
    size_t id)
{
    // instead of storing a void *, we just store our id
    // this is safe since GEOS doesn't access the item pointer
    GEOSSTRtree_insert_r(handle, tree, g, (void *)id);
}

// query with our custom callback
void IndexQuery(
    GEOSContextHandle_t handle,
    GEOSSTRtree *tree,
    const GEOSGeometry *g,
    void *userdata)
{
    GEOSSTRtree_query_r(handle, tree, g, IndexQuerySendCallback, userdata);
    }
*/
import "C"
<commit_msg>use larger buffer for geos error messages<commit_after>package geos

/*
#cgo LDFLAGS: -lgeos_c
#include "geos_c.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>

extern void goLogString(char *msg);
extern void goSendQueryResult(size_t, void *);

void debug_wrap(const char *fmt, ...) {
	va_list a_list;
    va_start(a_list, fmt);

	char buf[1024];
	vsnprintf(buf, sizeof(buf), fmt, a_list);
	va_end(a_list);
	goLogString((char *)&buf);
}

GEOSContextHandle_t initGEOS_r_debug() {
	return initGEOS_r(debug_wrap, debug_wrap);
}

void initGEOS_debug() {
    return initGEOS(debug_wrap, debug_wrap);
}

// wrap goIndexSendQueryResult
void IndexQuerySendCallback(void *item, void *userdata) {
    goIndexSendQueryResult((size_t)item, userdata);
}

void IndexAdd(
    GEOSContextHandle_t handle,
    GEOSSTRtree *tree,
    const GEOSGeometry *g,
    size_t id)
{
    // instead of storing a void *, we just store our id
    // this is safe since GEOS doesn't access the item pointer
    GEOSSTRtree_insert_r(handle, tree, g, (void *)id);
}

// query with our custom callback
void IndexQuery(
    GEOSContextHandle_t handle,
    GEOSSTRtree *tree,
    const GEOSGeometry *g,
    void *userdata)
{
    GEOSSTRtree_query_r(handle, tree, g, IndexQuerySendCallback, userdata);
    }
*/
import "C"
<|endoftext|>


<commit_before>package resource

import (
	"github.com/layeh/gopher-luar"
	"github.com/yuin/gopher-lua"
)

// LuaRegisterBuiltin registers resource providers in Lua
func LuaRegisterBuiltin(L *lua.LState) {
	// Go functions registered in Lua
	builtins := map[string]interface{}{
		"log": Log,
	}

	// Register functions in Lua
	for name, fn := range builtins {
		L.SetGlobal(name, luar.New(L, fn))
	}

	// The resource namespace in Lua
	namespace := L.NewTable()
	L.SetGlobal("resource", namespace)

	// Register resource providers in Lua
	for typ, provider := range providerRegistry {
		// Wrap resource providers, so that we can properly handle any
		// errors returned by providers during resource instantiation.
		// Since we don't want to return the error to Lua, this is the
		// place where we handle any errors returned by providers.
		wrapper := func(p Provider) lua.LGFunction {
			return func(L *lua.LState) int {
				// Create the resource by calling it's provider
				r, err := p(L.CheckString(1))
				if err != nil {
					L.RaiseError(err.Error())
				}

				L.Push(luar.New(L, r))
				return 1 // Number of arguments returned to Lua
			}
		}

		tbl := L.NewTable()
		tbl.RawSetH(lua.LString("new"), L.NewFunction(wrapper(provider)))
		L.SetField(namespace, typ, tbl)
	}
}
<commit_msg>resource: use a const for the default resource namespace<commit_after>package resource

import (
	"github.com/layeh/gopher-luar"
	"github.com/yuin/gopher-lua"
)

// DefaultNamespace is the Lua table where resources are being
// registered to, when using the default namespace.
const DefaultNamespace = "resource"

// LuaRegisterBuiltin registers resource providers in Lua
func LuaRegisterBuiltin(L *lua.LState) {
	// Go functions registered in Lua
	builtins := map[string]interface{}{
		"log": Log,
	}

	// Register functions in Lua
	for name, fn := range builtins {
		L.SetGlobal(name, luar.New(L, fn))
	}

	// The default resource namespace in Lua
	defaultNamespace := L.NewTable()
	L.SetGlobal(DefaultNamespace, defaultNamespace)

	// Register resource providers in Lua
	for typ, provider := range providerRegistry {
		// Wrap resource providers, so that we can properly handle any
		// errors returned by providers during resource instantiation.
		// Since we don't want to return the error to Lua, this is the
		// place where we handle any errors returned by providers.
		wrapper := func(p Provider) lua.LGFunction {
			return func(L *lua.LState) int {
				// Create the resource by calling it's provider
				r, err := p(L.CheckString(1))
				if err != nil {
					L.RaiseError(err.Error())
				}

				L.Push(luar.New(L, r))
				return 1 // Number of arguments returned to Lua
			}
		}

		tbl := L.NewTable()
		tbl.RawSetH(lua.LString("new"), L.NewFunction(wrapper(provider)))
		L.SetField(defaultNamespace, typ, tbl)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"koding/db/models"
	"koding/tools/utils"
	"koding/virt"
	"log"
	"net"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/jessevdk/go-flags"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

const (
	usage = `usage: <action> [<vm-id>|all]

	list
	start
	shutdown
	stop
	ip
	unprepare
	create-test-vms
	rbd-orphans
`
)

var flagOpts struct {
	Templates string `long:"templates" short:"t" description:"Change template dir." default:"files/templates"`
}

func main() {
	remainingArgs, err := flags.Parse(&flagOpts)
	if err != nil {
		log.Fatal(err)
	}

	if err := virt.LoadTemplates(flagOpts.Templates); err != nil {
		log.Fatal(err)
	}

	if len(remainingArgs) == 0 {
		fmt.Fprintf(os.Stderr, usage)
		os.Exit(0)
	}

	action := remainingArgs[0]
	actionArgs := remainingArgs[1:]

	fn := actions[action]
	fn(actionArgs)
}

var actions = map[string]func(args []string){
	"list": func(args []string) {
		dirs, err := ioutil.ReadDir("/var/lib/lxc")
		if err != nil {
			log.Println(err)
			return
		}

		for _, dir := range dirs {
			if strings.HasPrefix(dir.Name(), "vm-") {
				fmt.Println(dir.Name())
			}
		}

	},

	"start": func(args []string) {
		for _, vm := range selectVMs(args[0]) {
			err := vm.Start()
			fmt.Printf("%v: %v\n%s", vm, err)
		}
	},

	"shutdown": func(args []string) {
		for _, vm := range selectVMs(args[0]) {
			err := vm.Shutdown()
			fmt.Printf("%v: %v\n%s", vm, err)
		}
	},

	"stop": func(args []string) {
		for _, vm := range selectVMs(args[0]) {
			err := vm.Stop()
			fmt.Printf("%v: %v\n%s", vm, err)
		}
	},

	"unprepare": func(args []string) {
		if len(args) == 0 {
			log.Fatal("usage: unprepare <all | vm-id>")
		}

		for _, vm := range selectVMs(args[0]) {
			err := vm.Unprepare()
			fmt.Printf("%v: %v\n", vm, err)
		}
	},

	"ip": func(args []string) {
		if len(args) != 2 {
			log.Fatal("usage: ip <mongo-url> <vm-id>")
		}

		session, err := mgo.Dial(args[0])
		if err != nil {
			panic(err)
		}

		vm := new(models.VM)
		session.SetSafe(&mgo.Safe{})

		vmId := strings.TrimPrefix(args[1], "vm-")

		database := session.DB("")
		err = database.C("jVMs").Find(bson.M{"_id": bson.ObjectIdHex(vmId)}).One(vm)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		fmt.Println(vm.IP.String())
	},

	"create-test-vms": func(args []string) {
		startIP := net.IPv4(10, 128, 2, 7)
		if len(os.Args) >= 4 {
			startIP = net.ParseIP(os.Args[3])
		}
		ipPoolFetch, _ := utils.NewIntPool(utils.IPToInt(startIP), nil)
		count, _ := strconv.Atoi(args[0])

		done := make(chan string)
		for i := 0; i < count; i++ {
			go func(i int) {
				vm := virt.VM{
					Id: bson.NewObjectId(),
					IP: utils.IntToIP(<-ipPoolFetch),
				}
				vm.ApplyDefaults()
				fmt.Println(i, "preparing...")
				for _ = range vm.Prepare(false) {
				}

				fmt.Println(i, "starting...")
				if err := vm.Start(); err != nil {
					log.Println(i, "start", err)
				}

				// wait until network is up
				fmt.Println(i, "waiting...")
				if err := vm.WaitForNetwork(time.Second * 5); err != nil {
					log.Print(i, "WaitForNetwork", err)
				}
				done <- fmt.Sprintln(i, "ready", "vm-"+vm.Id.Hex())
			}(i)
		}

		for i := 0; i < count; i++ {
			fmt.Println(<-done)
		}
	},

	"rbd-orphans": func(args []string) {
		if len(args) == 0 {
			log.Fatal("usage: vmtool rbd-orphans <mongo-url>")
		}

		session, err := mgo.Dial(args[0])
		if err != nil {
			panic(err)
		}
		session.SetSafe(&mgo.Safe{})
		database := session.DB("")
		iter := database.C("jVMs").Find(bson.M{}).Select(bson.M{"_id": 1}).Iter()
		var vm struct {
			Id bson.ObjectId `bson:"_id"`
		}
		ids := make(map[string]bool)
		for iter.Next(&vm) {
			ids["vm-"+vm.Id.Hex()] = true
		}
		if err := iter.Close(); err != nil {
			panic(err)
		}

		cmd := exec.Command("/usr/bin/rbd", "ls", "--pool", "vms")
		pipe, _ := cmd.StdoutPipe()
		r := bufio.NewReader(pipe)
		if err := cmd.Start(); err != nil {
			panic(err)
		}
		fmt.Println("RBD images without corresponding database entry:")
		for {
			image, err := r.ReadString('\n')
			if err != nil {
				if err != io.EOF {
					panic(err)
				}
				break
			}
			image = image[:len(image)-1]

			if !ids[image] {
				fmt.Println(image)
			}
		}
	},
}

func selectVMs(selector string) []*virt.VM {
	if selector == "all" {
		dirs, err := ioutil.ReadDir("/var/lib/lxc")
		if err != nil {
			panic(err)
		}
		vms := make([]*virt.VM, 0)
		for _, dir := range dirs {
			if strings.HasPrefix(dir.Name(), "vm-") {
				vms = append(vms, &virt.VM{Id: bson.ObjectIdHex(dir.Name()[3:])})
			}
		}
		return vms
	}

	if strings.HasPrefix(selector, "vm-") {
		_, err := os.Stat("/var/lib/lxc/" + selector)
		if err != nil {
			if !os.IsNotExist(err) {
				panic(err)
			}
			fmt.Println("No prepared VM with name: " + selector)
			os.Exit(1)
		}
		return []*virt.VM{&virt.VM{Id: bson.ObjectIdHex(selector[3:])}}
	}

	fmt.Println("Invalid selector: " + selector)
	os.Exit(1)
	return nil
}
<commit_msg>vmtool: fix unpreparing. lxc's should be stopped before unpreparing<commit_after>package main

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"koding/db/models"
	"koding/tools/utils"
	"koding/virt"
	"log"
	"net"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/jessevdk/go-flags"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

const (
	usage = `usage: <action> [<vm-id>|all]

	list
	start
	shutdown
	stop
	ip
	unprepare
	create-test-vms
	rbd-orphans
`
)

var flagOpts struct {
	Templates string `long:"templates" short:"t" description:"Change template dir." default:"files/templates"`
}

func main() {
	remainingArgs, err := flags.Parse(&flagOpts)
	if err != nil {
		log.Fatal(err)
	}

	if err := virt.LoadTemplates(flagOpts.Templates); err != nil {
		log.Fatal(err)
	}

	if len(remainingArgs) == 0 {
		fmt.Fprintf(os.Stderr, usage)
		os.Exit(0)
	}

	action := remainingArgs[0]
	actionArgs := remainingArgs[1:]

	fn := actions[action]
	fn(actionArgs)
}

var actions = map[string]func(args []string){
	"list": func(args []string) {
		dirs, err := ioutil.ReadDir("/var/lib/lxc")
		if err != nil {
			log.Println(err)
			return
		}

		for _, dir := range dirs {
			if strings.HasPrefix(dir.Name(), "vm-") {
				fmt.Println(dir.Name())
			}
		}

	},

	"start": func(args []string) {
		for _, vm := range selectVMs(args[0]) {
			err := vm.Start()
			fmt.Printf("%v: %v\n", vm, err)
		}
	},

	"shutdown": func(args []string) {
		for _, vm := range selectVMs(args[0]) {
			err := vm.Shutdown()
			fmt.Printf("%v: %v\n", vm, err)
		}
	},

	"stop": func(args []string) {
		for _, vm := range selectVMs(args[0]) {
			err := vm.Stop()
			fmt.Printf("%v: %v\n", vm, err)
		}
	},

	"unprepare": func(args []string) {
		if len(args) == 0 {
			log.Fatal("usage: unprepare <all | vm-id>")
		}

		vms := selectVMs(args[0])

		for _, vm := range vms {
			err := vm.Shutdown()

			for step := range vm.Unprepare() {
				err = step.Err
			}
			fmt.Printf("%v: %v\n", vm, err)
		}
	},

	"ip": func(args []string) {
		if len(args) != 2 {
			log.Fatal("usage: ip <mongo-url> <vm-id>")
		}

		session, err := mgo.Dial(args[0])
		if err != nil {
			panic(err)
		}

		vm := new(models.VM)
		session.SetSafe(&mgo.Safe{})

		vmId := strings.TrimPrefix(args[1], "vm-")

		database := session.DB("")
		err = database.C("jVMs").Find(bson.M{"_id": bson.ObjectIdHex(vmId)}).One(vm)
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		fmt.Println(vm.IP.String())
	},

	"create-test-vms": func(args []string) {
		startIP := net.IPv4(10, 128, 2, 7)
		if len(os.Args) >= 4 {
			startIP = net.ParseIP(os.Args[3])
		}
		ipPoolFetch, _ := utils.NewIntPool(utils.IPToInt(startIP), nil)
		count, _ := strconv.Atoi(args[0])

		done := make(chan string)
		for i := 0; i < count; i++ {
			go func(i int) {
				vm := virt.VM{
					Id: bson.NewObjectId(),
					IP: utils.IntToIP(<-ipPoolFetch),
				}
				vm.ApplyDefaults()
				fmt.Println(i, "preparing...")
				for _ = range vm.Prepare(false) {
				}

				fmt.Println(i, "starting...")
				if err := vm.Start(); err != nil {
					log.Println(i, "start", err)
				}

				// wait until network is up
				fmt.Println(i, "waiting...")
				if err := vm.WaitForNetwork(time.Second * 5); err != nil {
					log.Print(i, "WaitForNetwork", err)
				}
				done <- fmt.Sprint(i, " vm-"+vm.Id.Hex())
			}(i)
		}

		for i := 0; i < count; i++ {
			fmt.Println(<-done)
		}
	},

	"rbd-orphans": func(args []string) {
		if len(args) == 0 {
			log.Fatal("usage: vmtool rbd-orphans <mongo-url>")
		}

		session, err := mgo.Dial(args[0])
		if err != nil {
			panic(err)
		}
		session.SetSafe(&mgo.Safe{})
		database := session.DB("")
		iter := database.C("jVMs").Find(bson.M{}).Select(bson.M{"_id": 1}).Iter()
		var vm struct {
			Id bson.ObjectId `bson:"_id"`
		}
		ids := make(map[string]bool)
		for iter.Next(&vm) {
			ids["vm-"+vm.Id.Hex()] = true
		}
		if err := iter.Close(); err != nil {
			panic(err)
		}

		cmd := exec.Command("/usr/bin/rbd", "ls", "--pool", "vms")
		pipe, _ := cmd.StdoutPipe()
		r := bufio.NewReader(pipe)
		if err := cmd.Start(); err != nil {
			panic(err)
		}
		fmt.Println("RBD images without corresponding database entry:")
		for {
			image, err := r.ReadString('\n')
			if err != nil {
				if err != io.EOF {
					panic(err)
				}
				break
			}
			image = image[:len(image)-1]

			if !ids[image] {
				fmt.Println(image)
			}
		}
	},
}

func selectVMs(selector string) []*virt.VM {
	if selector == "all" {
		dirs, err := ioutil.ReadDir("/var/lib/lxc")
		if err != nil {
			panic(err)
		}
		vms := make([]*virt.VM, 0)
		for _, dir := range dirs {
			if strings.HasPrefix(dir.Name(), "vm-") {
				vms = append(vms, &virt.VM{Id: bson.ObjectIdHex(dir.Name()[3:])})
			}
		}
		return vms
	}

	if strings.HasPrefix(selector, "vm-") {
		_, err := os.Stat("/var/lib/lxc/" + selector)
		if err != nil {
			if !os.IsNotExist(err) {
				panic(err)
			}
			fmt.Println("No prepared VM with name: " + selector)
			os.Exit(1)
		}
		return []*virt.VM{&virt.VM{Id: bson.ObjectIdHex(selector[3:])}}
	}

	fmt.Println("Invalid selector: " + selector)
	os.Exit(1)
	return nil
}
<|endoftext|>


<commit_before>package rest

import (
	"encoding/json"
	"fmt"
	"socialapi/models"
	"socialapi/request"

	"github.com/google/go-querystring/query"
)

// CreateLink creates a link between two channels
func CreateLink(rootId, leafId int64, token string) (*models.ChannelLink, error) {
	data := &models.ChannelLink{RootId: rootId, LeafId: leafId}
	url := fmt.Sprintf("/moderation/channel/%d/link", rootId)
	cl, err := sendModelWithAuth("POST", url, data, token)
	if err != nil {
		return nil, err
	}

	return cl.(*models.ChannelLink), nil
}

// GetLinks retunrs leaves of the given root channel
func GetLinks(rootId int64, q *request.Query, token string) ([]models.Channel, error) {
	v, err := query.Values(q)
	if err != nil {
		return nil, err
	}

	url := fmt.Sprintf("/moderation/channel/%d/link?%s", rootId, v.Encode())
	res, err := sendRequestWithAuth("GET", url, nil, token)
	if err != nil {
		return nil, err
	}

	var link []models.Channel
	err = json.Unmarshal(res, &link)
	if err != nil {
		return nil, err
	}

	return link, nil
}

// Unlink removes the link between two channels
func UnLink(rootId, leafId int64, token string) error {
	url := fmt.Sprintf("/moderation/channel/%d/link/%d", rootId, leafId)
	_, err := sendRequestWithAuth("DELETE", url, nil, token)
	return err
}

// BlackList deletes the channel and blocks it from re-creation as a channel
func BlackList(rootId int64, token string) error {
	url := fmt.Sprintf("/moderation/channel/%d", rootId)
	_, err := sendRequestWithAuth("DELETE", url, nil, token)
	return err
}
<commit_msg>Socialapi: change the order of ids<commit_after>package rest

import (
	"encoding/json"
	"fmt"
	"socialapi/models"
	"socialapi/request"

	"github.com/google/go-querystring/query"
)

// CreateLink creates a link between two channels
func CreateLink(rootId, leafId int64, token string) (*models.ChannelLink, error) {
	data := &models.ChannelLink{RootId: rootId, LeafId: leafId}
	url := fmt.Sprintf("/moderation/channel/%d/link", rootId)
	cl, err := sendModelWithAuth("POST", url, data, token)
	if err != nil {
		return nil, err
	}

	return cl.(*models.ChannelLink), nil
}

// GetLinks retunrs leaves of the given root channel
func GetLinks(rootId int64, q *request.Query, token string) ([]models.Channel, error) {
	v, err := query.Values(q)
	if err != nil {
		return nil, err
	}

	url := fmt.Sprintf("/moderation/channel/%d/link?%s", rootId, v.Encode())
	res, err := sendRequestWithAuth("GET", url, nil, token)
	if err != nil {
		return nil, err
	}

	var link []models.Channel
	err = json.Unmarshal(res, &link)
	if err != nil {
		return nil, err
	}

	return link, nil
}

// Unlink removes the link between two channels
func UnLink(rootId, leafId int64, token string) error {
	url := fmt.Sprintf("/moderation/channel/%d/link/%d", rootId, leafId)
	_, err := sendRequestWithAuth("DELETE", url, nil, token)
	return err
}

// BlackList deletes the channel and blocks it from re-creation as a channel
func BlackList(rootId, leafId int64, token string) error {
	url := fmt.Sprintf("/moderation/channel/%d?rootId=%d", leafId, rootId)
	_, err := sendRequestWithAuth("DELETE", url, nil, token)
	return err
}
<|endoftext|>


<commit_before>package reverseproxy

import (
    "io"
    "errors"
    "fmt"
    "log"
    "net"
    "net/http"
    "net/url"
    "strings"
    "sync"
    "time"

    "github.com/oxtoacart/bpool"
)

// HTTP proxy application
// This interface encapsulates the methods that the HTTP
// processing application needs to implement to
// use the reverse proxy service
// - a handler to process HTTP Requests
// - a handler to process HTTP Responses
type HttpApplication interface {
    RequestHandler(req *http.Request) error
    ResponseHandler(resp *http.Response) error
}

// onExitFlushLoop is a callback set by tests to detect the state of the
// flushLoop() goroutine.
var onExitFlushLoop func()

// ErrResponseShortWrite means that a write accepted fewer bytes than requested
// but failed to return an explicit error.
var ErrResponseShortWrite = errors.New("short write")

/*
 *  HTTP reverse proxy using the standard library reverse proxy
 *
 *    target:
 */
type HttpReverseProxy struct {
    // Director must be a function that modified the request into a new
    // request to be sent using Transport. Its response is then copied
    // back to the client
    Director func(*http.Request)

    // The transport used to perform proxy requests.
    // If nil, http.DefaultTransport is used
    Transport *ProxyTransport

    // FlushInterval specifies the flush interval to flush to the client
    // while copying the response body.
    // If zero, no periodic flushing is done
    FlushInterval time.Duration

    // ErrorLog specifies an optional logger for errors that occur when
    // attempting to process the request. If nil, logging goes to os.Stderr
    // using the standard logger
    ErrorLog *log.Logger

    // BufferPool specifies a buffer pool to get byte slices for use by
    // io.CopyBuffer when copying HTTP request and response bodies
    BufferPool *bpool.BytePool

    // The application that is processes the HTTP data as it is
    // streamed to/from the server being proxied
    app    HttpApplication
}

func NewHttpReverseProxy(target *url.URL, app HttpApplication) (*HttpReverseProxy, error) {

    pool := bpool.NewBytePool(20, 524288)
    director := func(req *http.Request) {
        targetQuery := target.RawQuery
        req.URL.Scheme = target.Scheme
        req.URL.Host = target.Host
        if targetQuery == "" || req.URL.RawQuery == "" {
            req.URL.RawQuery = targetQuery + req.URL.RawQuery
        } else {
            req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
        }
        //update the host header in the request
        req.Host = target.Host
    }

    return &HttpReverseProxy{
        Director: director,
        Transport: &ProxyTransport{},
        BufferPool: pool,
        app: app,
    }, nil
}

func copyHeader(dst, src http.Header) {
	for k, vv := range src {
		for _, v := range vv {
			dst.Add(k, v)
		}
	}
}

func (p *HttpReverseProxy) Start() error {
    fmt.Printf("Starting Object Store service on port 8080\n");
    //https://husobee.github.io/golang/tls/2016/01/27/golang-tls.html
    connStateHandler := func (c net.Conn, state http.ConnState) {
        // we are interested only in closed connections.
        // On a conn close, cleanup the corresponding backend connection
        // to the Server.
        if state == http.StateClosed {
            remote := c.RemoteAddr().String()
            transport := p.Transport

            transport.ClientClose(remote)
        }
    }
    server := &http.Server{
        Addr: ":8080",
        ConnState: connStateHandler,
        Handler: p,
    }
    server.ListenAndServe()
    return nil
}

// Hop-by-hop headers. These are removed when sent to the backend.
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
var hopHeaders = []string{
	"Connection",
	"Proxy-Connection", // non-standard but still sent by libcurl and rejected by e.g. google
	"Keep-Alive",
	"Proxy-Authenticate",
	"Proxy-Authorization",
	"Te",      // canonicalized version of "TE"
	"Trailer", // not Trailers per URL above; http://www.rfc-editor.org/errata_search.php?eid=4522
	"Transfer-Encoding",
	"Upgrade",
}

func (p *HttpReverseProxy) processRequest(req *http.Request) (*http.Response, error) {
    transport := p.Transport

    //first get the connection object
    conn, err := transport.GetConnection(req)
    if err != nil {
        fmt.Printf("proxy: Failed to get a connection to the backend server: %s\n", err)
        return nil, err
    }

    err = transport.WriteHeader(conn, req)
    if err != nil {
        fmt.Printf("proxy: Failed to send Request Headers to backend: %s\n", err)
        return nil, err
    }

    written := 0
    // write the body out, if there is one
    if req.Body != nil {
        src := req.Body
        fmt.Printf("Content Length is %d\n", req.Header.Get("Content-Length"))

        var buf []byte
        for {
            buf := p.BufferPool.Get()
            nr, err := src.Read(buf)
            if nr > 0 {
                nw, err := transport.Write(conn, req, buf[0:nr])
                if err != nil {
                    fmt.Printf("Error: Writing request body\n")
                    break
                }
                if nw != nr {
                    fmt.Printf("Error: ShortRequestWrite\n")
                    break
                }
                written += nw
                fmt.Printf("Written %d bytes\n", written)
            }
            if err == io.EOF {
                break
            }
        }
        p.BufferPool.Put(buf)
    }
    resp, err := transport.ReadResponse(conn, req)
    transport.PutConnection(conn)
    return resp, err
}

func (p *HttpReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {

	outreq := new(http.Request)
	*outreq = *req // includes shallow copies of maps, but okay
    if req.ContentLength == 0 {
        outreq.Body = nil
    }

	p.Director(outreq)
	outreq.Proto = "HTTP/1.1"
	outreq.ProtoMajor = 1
	outreq.ProtoMinor = 1
	outreq.Close = false

    // Remove hop-by-hop headers listed in the "Connection" header.
	// See RFC 2616, section 14.10.
	copiedHeaders := false
	if c := outreq.Header.Get("Connection"); c != "" {
		for _, f := range strings.Split(c, ",") {
			if f = strings.TrimSpace(f); f != "" {
				if !copiedHeaders {
					outreq.Header = make(http.Header)
					copyHeader(outreq.Header, req.Header)
					copiedHeaders = true
				}
				outreq.Header.Del(f)
			}
		}
	}
	// Remove hop-by-hop headers to the backend.  Especially
	// important is "Connection" because we want a persistent
	// connection, regardless of what the client sent to us.  This
	// is modifying the same underlying map from req (shallow
	// copied above) so we only copy it if necessary.
	for _, h := range hopHeaders {
		if outreq.Header.Get(h) != "" {
			if !copiedHeaders {
				outreq.Header = make(http.Header)
				copyHeader(outreq.Header, req.Header)
				copiedHeaders = true
			}
			outreq.Header.Del(h)
		}
	}

    //now call the app handlers if registered
    //p.app.RequestHandler(outreq)

    //send this request on its way out
    res, err := p.processRequest(outreq)

    //res, err := transport.RoundTrip(outreq)
	if err != nil {
        p.logf("http: proxy error: %v", err)
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}
	defer res.Body.Close()

	for _, h := range hopHeaders {
		res.Header.Del(h)
	}

    //now call the app handlers if registered
    p.app.ResponseHandler(res)

	copyHeader(rw.Header(), res.Header)

	rw.WriteHeader(res.StatusCode)
	p.copyResponse(rw, res.Body)
}

func (p *HttpReverseProxy) copyResponse(dst io.Writer, src io.Reader) (written int64, err error) {
	if p.FlushInterval != 0 {
		if wf, ok := dst.(writeFlusher); ok {
			mlw := &maxLatencyWriter{
				dst:     wf,
				latency: p.FlushInterval,
				done:    make(chan bool),
			}
			go mlw.flushLoop()
			defer mlw.stop()
			dst = mlw
		}
	}
    var buf []byte
	for {
        buf = p.BufferPool.Get()
		nr, er := src.Read(buf)
		if nr > 0 {
            // invoke the application callback, if registered
            // app may modify the request and return a different
            // buffer. Also buffer here needs to be larger than
            // the data being read, so that app handler can
            // modify contents and return update buffer.
			nw, ew := dst.Write(buf[0:nr])
			if nw > 0 {
				written += int64(nw)
			}
			if ew != nil {
				err = ew
				break
			}
			if nr != nw {
				err = ErrResponseShortWrite
				break
			}
		}
		if er == io.EOF {
			break
		}
		if er != nil {
			err = er
			break
		}
	}
    p.BufferPool.Put(buf)
    return written, err
}

func (p *HttpReverseProxy) logf(format string, args ...interface{}) {
	if p.ErrorLog != nil {
		p.ErrorLog.Printf(format, args...)
	} else {
		log.Printf(format, args...)
	}
}

type writeFlusher interface {
	io.Writer
	http.Flusher
}

type maxLatencyWriter struct {
	dst     writeFlusher
	latency time.Duration

	lk   sync.Mutex // protects Write + Flush
	done chan bool
}

func (m *maxLatencyWriter) Write(p []byte) (int, error) {
	m.lk.Lock()
	defer m.lk.Unlock()
	return m.dst.Write(p)
}

func (m *maxLatencyWriter) flushLoop() {
	t := time.NewTicker(m.latency)
	defer t.Stop()
	for {
		select {
		case <-m.done:
			if onExitFlushLoop != nil {
				onExitFlushLoop()
			}
			return
		case <-t.C:
			m.lk.Lock()
			m.dst.Flush()
			m.lk.Unlock()
		}
	}
}

func (m *maxLatencyWriter) stop() {
    m.done <- true
}
<commit_msg>Encapsulate the http transaction in a flow object<commit_after>package reverseproxy

import (
	"errors"
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
	"net/url"
	"strings"
	"sync"
	"time"

	"github.com/oxtoacart/bpool"
	"github.com/pborman/uuid"
)

// HTTP proxy application
// This interface encapsulates the methods that the HTTP
// processing application needs to implement to
// use the reverse proxy service
// - a handler to process HTTP Requests
// - a handler to process HTTP Responses
type HttpApplication interface {
	RequestHandler(flow *HttpFlow) error
	ResponseHandler(flow *HttpFlow) error
	RequestDataHandler(flow *HttpFlow, buf []byte) error
	ResponseDataHandler(resp *HttpFlow, buf []byte) error
}

// ErrResponseShortWrite means that a write accepted fewer bytes than requested
// but failed to return an explicit error.
var ErrResponseShortWrite = errors.New("short write")

type HttpFlow struct {
	Id       string
	Request  *http.Request
	Response *http.Response
}

func Uuid() string {
	return uuid.New()
}

/*
 *  HTTP reverse proxy using the standard library reverse proxy
 *
 *    target:
 */
type HttpReverseProxy struct {
	// Director must be a function that modified the request into a new
	// request to be sent using Transport. Its response is then copied
	// back to the client
	Director func(*http.Request)

	// The transport used to perform proxy requests.
	// If nil, http.DefaultTransport is used
	Transport *ProxyTransport

	// ErrorLog specifies an optional logger for errors that occur when
	// attempting to process the request. If nil, logging goes to os.Stderr
	// using the standard logger
	ErrorLog *log.Logger

	// BufferPool specifies a buffer pool to get byte slices for use by
	// io.CopyBuffer when copying HTTP request and response bodies
	BufferPool *bpool.BytePool

	// The application that is processes the HTTP data as it is
	// streamed to/from the server being proxied
	app HttpApplication
}

func NewHttpReverseProxy(target *url.URL, app HttpApplication) (*HttpReverseProxy, error) {

	pool := bpool.NewBytePool(20, 524288)
	director := func(req *http.Request) {
		targetQuery := target.RawQuery
		req.URL.Scheme = target.Scheme
		req.URL.Host = target.Host
		if targetQuery == "" || req.URL.RawQuery == "" {
			req.URL.RawQuery = targetQuery + req.URL.RawQuery
		} else {
			req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
		}
		//update the host header in the request
		req.Host = target.Host
	}

	return &HttpReverseProxy{
		Director:   director,
		Transport:  &ProxyTransport{},
		BufferPool: pool,
		app:        app,
	}, nil
}

func copyHeader(dst, src http.Header) {
	for k, vv := range src {
		for _, v := range vv {
			dst.Add(k, v)
		}
	}
}

func (p *HttpReverseProxy) Start() error {
	fmt.Printf("Starting Reverse Proxy service on port 8080\n")
	//https://husobee.github.io/golang/tls/2016/01/27/golang-tls.html
	connStateHandler := func(c net.Conn, state http.ConnState) {
		// we are interested only in closed connections.
		// On a conn close, cleanup the corresponding backend connection
		// to the Server.
		if state == http.StateClosed {
			remote := c.RemoteAddr().String()
			transport := p.Transport

			transport.ClientClose(remote)
		}
	}
	server := &http.Server{
		Addr:      ":8080",
		ConnState: connStateHandler,
		Handler:   p,
	}
	server.ListenAndServe()
	return nil
}

// Hop-by-hop headers. These are removed when sent to the backend.
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
var hopHeaders = []string{
	"Connection",
	"Proxy-Connection", // non-standard but still sent by libcurl and rejected by e.g. google
	"Keep-Alive",
	"Proxy-Authenticate",
	"Proxy-Authorization",
	"Te",      // canonicalized version of "TE"
	"Trailer", // not Trailers per URL above; http://www.rfc-editor.org/errata_search.php?eid=4522
	"Transfer-Encoding",
	"Upgrade",
}

func (p *HttpReverseProxy) processRequest(req *http.Request) (*http.Response, error) {
	transport := p.Transport

	//first get the connection object
	conn, err := transport.GetConnection(req)
	if err != nil {
		fmt.Printf("proxy: Failed to get a connection to the backend server: %s\n", err)
		return nil, err
	}

	err = transport.WriteHeader(conn, req)
	if err != nil {
		fmt.Printf("proxy: Failed to send Request Headers to backend: %s\n", err)
		return nil, err
	}

	written := 0
	// write the body out, if there is one
	if req.Body != nil {
		src := req.Body
		fmt.Printf("Content Length is %d\n", req.Header.Get("Content-Length"))

		var buf []byte
		for {
			buf := p.BufferPool.Get()
			nr, err := src.Read(buf)
			if nr > 0 {
				nw, err := transport.Write(conn, req, buf[0:nr])
				if err != nil {
					fmt.Printf("Error: Writing request body\n")
					break
				}
				if nw != nr {
					fmt.Printf("Error: ShortRequestWrite\n")
					break
				}
				written += nw
				fmt.Printf("Written %d bytes\n", written)
			}
			if err == io.EOF {
				break
			}
		}
		p.BufferPool.Put(buf)
	}
	resp, err := transport.ReadResponse(conn, req)
	transport.PutConnection(conn)
	return resp, err
}

func (p *HttpReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {

	outreq := new(http.Request)
	*outreq = *req // includes shallow copies of maps, but okay
	if req.ContentLength == 0 {
		outreq.Body = nil
	}

	p.Director(outreq)
	outreq.Proto = "HTTP/1.1"
	outreq.ProtoMajor = 1
	outreq.ProtoMinor = 1
	outreq.Close = false

	// Remove hop-by-hop headers listed in the "Connection" header.
	// See RFC 2616, section 14.10.
	copiedHeaders := false
	if c := outreq.Header.Get("Connection"); c != "" {
		for _, f := range strings.Split(c, ",") {
			if f = strings.TrimSpace(f); f != "" {
				if !copiedHeaders {
					outreq.Header = make(http.Header)
					copyHeader(outreq.Header, req.Header)
					copiedHeaders = true
				}
				outreq.Header.Del(f)
			}
		}
	}
	// Remove hop-by-hop headers to the backend.  Especially
	// important is "Connection" because we want a persistent
	// connection, regardless of what the client sent to us.  This
	// is modifying the same underlying map from req (shallow
	// copied above) so we only copy it if necessary.
	for _, h := range hopHeaders {
		if outreq.Header.Get(h) != "" {
			if !copiedHeaders {
				outreq.Header = make(http.Header)
				copyHeader(outreq.Header, req.Header)
				copiedHeaders = true
			}
			outreq.Header.Del(h)
		}
	}
	// create the flow object
	flow := &HttpFlow{
		Id:       Uuid(),
		Request:  outreq,
		Response: nil,
	}
	//now call the app handlers if registered
	p.app.RequestHandler(flow)

	//send this request on its way out
	err := p.processRequest(flow)
	if err != nil {
		p.logf("http: proxy error: %v", err)
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}
	defer flow.Response.Body.Close()

	for _, h := range hopHeaders {
		flow.Response.Header.Del(h)
	}

	//now call the app handlers if registered
	p.app.ResponseHandler(flow)

	copyHeader(rw.Header(), flow.response.Header)

	rw.WriteHeader(res.StatusCode)
	p.copyResponse(rw, flow)
}

func (p *HttpReverseProxy) copyResponse(dst io.Writer, flow *HttpFlow) (written int64, err error) {
	src := flow.Response.Body

	var buf []byte
	for {
		buf = p.BufferPool.Get()
		nr, er := src.Read(buf)
		if nr > 0 {
			// invoke the application callback, if registered
			// app may modify the request and return a different
			// buffer. Also buffer here needs to be larger than
			// the data being read, so that app handler can
			// modify contents and return update buffer.
			nw, ew := dst.Write(buf[0:nr])
			if nw > 0 {
				written += int64(nw)
			}
			if ew != nil {
				err = ew
				break
			}
			if nr != nw {
				err = ErrResponseShortWrite
				break
			}
		}
		if er == io.EOF {
			break
		}
		if er != nil {
			err = er
			break
		}
	}
	p.BufferPool.Put(buf)
	return written, err
}

func (p *HttpReverseProxy) logf(format string, args ...interface{}) {
	if p.ErrorLog != nil {
		p.ErrorLog.Printf(format, args...)
	} else {
		log.Printf(format, args...)
	}
}
<|endoftext|>


<commit_before>// Copyright 2019 The Go Authors. All rights reserved.
// Copyright 2019 George Tankersley. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package ristretto255 implements the ristretto255 prime-order group as
// specified in draft-hdevalence-cfrg-ristretto-00.
package ristretto255

import (
	"errors"

	"github.com/gtank/ristretto255/internal/edwards25519"
	"github.com/gtank/ristretto255/internal/radix51"
)

var (
	sqrtM1 = fieldElementFromDecimal(
		"19681161376707505956807079304988542015446066515923890162744021073123829784752")
	sqrtADMinusOne = fieldElementFromDecimal(
		"25063068953384623474111414158702152701244531502492656460079210482610430750235")
	invSqrtAMinusD = fieldElementFromDecimal(
		"54469307008909316920995813868745141605393597292927456921205312896311721017578")
	oneMinusDSQ = fieldElementFromDecimal(
		"1159843021668779879193775521855586647937357759715417654439879720876111806838")
	dMinusOneSQ = fieldElementFromDecimal(
		"40440834346308536858101042469323190826248399146238708352240133220865137265952")

	errInvalidEncoding = errors.New("invalid Ristretto encoding")
)

// Element is an element of the ristretto255 prime-order group.
type Element struct {
	r edwards25519.ExtendedGroupElement
}

// Equal returns 1 if e is equivalent to ee, and 0 otherwise.
// Note that Elements must not be compared in any other way.
func (e *Element) Equal(ee *Element) int {
	var f0, f1 radix51.FieldElement

	f0.Mul(&e.r.X, &ee.r.Y) // x1 * y2
	f1.Mul(&e.r.Y, &ee.r.X) // y1 * x2
	out := f0.Equal(&f1)

	f0.Mul(&e.r.Y, &ee.r.Y) // y1 * y2
	f1.Mul(&e.r.X, &ee.r.X) // x1 * x2
	out = out | f0.Equal(&f1)

	return out
}

// FromUniformBytes maps the 64-byte slice b to an Element e uniformly and
// deterministically. This can be used for hash-to-group operations or to obtain
// a random element.
func (e *Element) FromUniformBytes(b []byte) {
	if len(b) != 64 {
		panic("ristretto255: FromUniformBytes: input is not 64 bytes long")
	}

	f := &radix51.FieldElement{}

	f.FromBytes(b[:32])
	p1 := &edwards25519.ExtendedGroupElement{}
	mapToPoint(p1, f)

	f.FromBytes(b[32:])
	p2 := &edwards25519.ExtendedGroupElement{}
	mapToPoint(p2, f)

	e.r.Add(p1, p2)
}

// mapToPoint implements MAP from Section 3.2.4 of draft-hdevalence-cfrg-ristretto-00.
func mapToPoint(out *edwards25519.ExtendedGroupElement, t *radix51.FieldElement) {
	// r = SQRT_M1 * t^2
	r := &radix51.FieldElement{}
	r.Mul(sqrtM1, r.Square(t))

	// u = (r + 1) * ONE_MINUS_D_SQ
	u := &radix51.FieldElement{}
	u.Mul(u.Add(r, radix51.One), oneMinusDSQ)

	// c = -1
	c := &radix51.FieldElement{}
	c.Set(radix51.MinusOne)

	// v = (c - r*D) * (r + D)
	rPlusD := &radix51.FieldElement{}
	rPlusD.Add(r, edwards25519.D)
	v := &radix51.FieldElement{}
	v.Mul(v.Sub(c, v.Mul(r, edwards25519.D)), rPlusD)

	// (was_square, s) = SQRT_RATIO_M1(u, v)
	s := &radix51.FieldElement{}
	wasSquare := feSqrtRatio(s, u, v)

	// s_prime = -CT_ABS(s*t)
	sPrime := &radix51.FieldElement{}
	sPrime.Neg(sPrime.Abs(sPrime.Mul(s, t)))

	// s = CT_SELECT(s IF was_square ELSE s_prime)
	s.Select(s, sPrime, wasSquare)
	// c = CT_SELECT(c IF was_square ELSE r)
	c.Select(c, r, wasSquare)

	// N = c * (r - 1) * D_MINUS_ONE_SQ - v
	N := &radix51.FieldElement{}
	N.Mul(c, N.Sub(r, radix51.One))
	N.Sub(N.Mul(N, dMinusOneSQ), v)

	s2 := &radix51.FieldElement{}
	s2.Square(s)

	// w0 = 2 * s * v
	w0 := &radix51.FieldElement{}
	w0.Add(w0, w0.Mul(s, v))
	// w1 = N * SQRT_AD_MINUS_ONE
	w1 := &radix51.FieldElement{}
	w1.Mul(N, sqrtADMinusOne)
	// w2 = 1 - s^2
	w2 := &radix51.FieldElement{}
	w2.Sub(radix51.One, s2)
	// w3 = 1 + s^2
	w3 := &radix51.FieldElement{}
	w3.Add(radix51.One, s2)

	// return (w0*w3, w2*w1, w1*w3, w0*w2)
	out.X.Mul(w0, w3)
	out.Y.Mul(w2, w1)
	out.Z.Mul(w1, w3)
	out.T.Mul(w0, w2)
}

// Encode encodes a Ristretto group element to its canonical bytestring.
func (ee *Element) Encode() []byte {
	tmp := &radix51.FieldElement{}

	// u1 = (z0 + y0) * (z0 - y0)
	u1 := &radix51.FieldElement{}
	u1.Add(&ee.r.Z, &ee.r.Y).Mul(u1, tmp.Sub(&ee.r.Z, &ee.r.Y))

	// u2 = x0 * y0
	u2 := &radix51.FieldElement{}
	u2.Mul(&ee.r.X, &ee.r.Y)

	// Ignore was_square since this is always square
	// (_, invsqrt) = SQRT_RATIO_M1(1, u1 * u2^2)
	invSqrt := &radix51.FieldElement{}
	_ = feSqrtRatio(invSqrt, u1, tmp.Square(u2))

	// den1 = invsqrt * u1
	// den2 = invsqrt * u2
	// z_inv = den1 * den2 * t0
	den1, den2 := &radix51.FieldElement{}, &radix51.FieldElement{}
	zInv := &radix51.FieldElement{}
	den1.Mul(invSqrt, u1)
	den2.Mul(invSqrt, u2)
	zInv.Mul(den1, den2).Mul(zInv, &ee.r.T)

	// ix0 = x0 * SQRT_M1
	// iy0 = y0 * SQRT_M1
	// enchanted_denominator = den1 * INVSQRT_A_MINUS_D
	ix0, iy0 := &radix51.FieldElement{}, &radix51.FieldElement{}
	enchantedDenominator := &radix51.FieldElement{}
	ix0.Mul(&ee.r.X, sqrtM1)
	iy0.Mul(&ee.r.Y, sqrtM1)
	enchantedDenominator.Mul(den1, invSqrtAMinusD)

	// rotate = IS_NEGATIVE(t0 * z_inv)
	rotate := tmp.Mul(&ee.r.T, zInv).IsNegative()

	// x = CT_SELECT(iy0 IF rotate ELSE x0)
	// y = CT_SELECT(ix0 IF rotate ELSE y0)
	// z = z0
	// den_inv = CT_SELECT(enchanted_denominator IF rotate ELSE den2)
	x, y := &radix51.FieldElement{}, &radix51.FieldElement{}
	denInv := &radix51.FieldElement{}
	x.Select(iy0, &ee.r.X, rotate)
	y.Select(ix0, &ee.r.Y, rotate)
	z := &ee.r.Z
	denInv.Select(enchantedDenominator, den2, rotate)

	// y = CT_NEG(y, IS_NEGATIVE(x * z_inv))
	y.CondNeg(y, tmp.Mul(x, zInv).IsNegative())

	// s = CT_ABS(den_inv * (z - y))
	s := tmp.Mul(denInv, tmp.Sub(z, y)).Abs(tmp)

	// Return the canonical little-endian encoding of s.
	return s.Bytes(nil)
}

// Decode decodes the canonical bytestring encoding of an element into a Ristretto element.
// Returns nil on success.
func (e *Element) Decode(in []byte) error {
	if len(in) != 32 {
		return errInvalidEncoding
	}

	// First, interpret the string as an integer s in little-endian representation.
	s := &radix51.FieldElement{}
	s.FromBytes(in)

	// If the resulting value is >= p, decoding fails.
	// If IS_NEGATIVE(s) returns TRUE, decoding fails.
	if !feMinimal(s) || s.IsNegative() == 1 {
		return errInvalidEncoding
	}

	// ss = s^2
	sSqr := &radix51.FieldElement{}
	sSqr.Square(s)

	// u1 = 1 - ss
	u1 := &radix51.FieldElement{}
	u1.Sub(radix51.One, sSqr)

	// u2 = 1 + ss
	u2 := &radix51.FieldElement{}
	u2.Add(radix51.One, sSqr)

	// u2_sqr = u2^2
	u2Sqr := &radix51.FieldElement{}
	u2Sqr.Square(u2)

	// v = -(D * u1^2) - u2_sqr
	v := &radix51.FieldElement{}
	v.Square(u1).Mul(v, edwards25519.D).Neg(v).Sub(v, u2Sqr)

	// (was_square, invsqrt) = SQRT_RATIO_M1(1, v * u2_sqr)
	invSqrt, tmp := &radix51.FieldElement{}, &radix51.FieldElement{}
	wasSquare := feSqrtRatio(invSqrt, radix51.One, tmp.Mul(v, u2Sqr))

	// den_x = invsqrt * u2
	// den_y = invsqrt * den_x * v
	denX, denY := &radix51.FieldElement{}, &radix51.FieldElement{}
	denX.Mul(invSqrt, u2)
	denY.Mul(invSqrt, denX).Mul(denY, v)

	// x = CT_ABS(2 * s * den_x)
	// y = u1 * den_y
	// t = x * y
	out := &e.r
	out.X.Mul(radix51.Two, s).Mul(&out.X, denX).Abs(&out.X)
	out.Y.Mul(u1, denY)
	out.Z.One()
	out.T.Mul(&out.X, &out.Y)

	// If was_square is FALSE, or IS_NEGATIVE(t) returns TRUE, or y = 0, decoding fails.
	if wasSquare == 0 || out.T.IsNegative() == 1 || out.Y.Equal(radix51.Zero) == 1 {
		return errInvalidEncoding
	}

	// Otherwise, return the internal representation in extended coordinates (x, y, 1, t).
	return nil
}

func (v *Element) Add(p, q *Element) *Element {
	v.r.Add(&p.r, &q.r)
	return v
}

func (v *Element) Sub(p, q *Element) *Element {
	v.r.Sub(&p.r, &q.r)
	return v
}

func (v *Element) Neg(p *Element) *Element {
	v.r.Neg(&p.r)
	return v
}
<commit_msg>ristretto255: add docs for Add, Sub, Neg<commit_after>// Copyright 2019 The Go Authors. All rights reserved.
// Copyright 2019 George Tankersley. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package ristretto255 implements the ristretto255 prime-order group as
// specified in draft-hdevalence-cfrg-ristretto-00.
package ristretto255

import (
	"errors"

	"github.com/gtank/ristretto255/internal/edwards25519"
	"github.com/gtank/ristretto255/internal/radix51"
)

var (
	sqrtM1 = fieldElementFromDecimal(
		"19681161376707505956807079304988542015446066515923890162744021073123829784752")
	sqrtADMinusOne = fieldElementFromDecimal(
		"25063068953384623474111414158702152701244531502492656460079210482610430750235")
	invSqrtAMinusD = fieldElementFromDecimal(
		"54469307008909316920995813868745141605393597292927456921205312896311721017578")
	oneMinusDSQ = fieldElementFromDecimal(
		"1159843021668779879193775521855586647937357759715417654439879720876111806838")
	dMinusOneSQ = fieldElementFromDecimal(
		"40440834346308536858101042469323190826248399146238708352240133220865137265952")

	errInvalidEncoding = errors.New("invalid Ristretto encoding")
)

// Element is an element of the ristretto255 prime-order group.
type Element struct {
	r edwards25519.ExtendedGroupElement
}

// Equal returns 1 if e is equivalent to ee, and 0 otherwise.
// Note that Elements must not be compared in any other way.
func (e *Element) Equal(ee *Element) int {
	var f0, f1 radix51.FieldElement

	f0.Mul(&e.r.X, &ee.r.Y) // x1 * y2
	f1.Mul(&e.r.Y, &ee.r.X) // y1 * x2
	out := f0.Equal(&f1)

	f0.Mul(&e.r.Y, &ee.r.Y) // y1 * y2
	f1.Mul(&e.r.X, &ee.r.X) // x1 * x2
	out = out | f0.Equal(&f1)

	return out
}

// FromUniformBytes maps the 64-byte slice b to an Element e uniformly and
// deterministically. This can be used for hash-to-group operations or to obtain
// a random element.
func (e *Element) FromUniformBytes(b []byte) {
	if len(b) != 64 {
		panic("ristretto255: FromUniformBytes: input is not 64 bytes long")
	}

	f := &radix51.FieldElement{}

	f.FromBytes(b[:32])
	p1 := &edwards25519.ExtendedGroupElement{}
	mapToPoint(p1, f)

	f.FromBytes(b[32:])
	p2 := &edwards25519.ExtendedGroupElement{}
	mapToPoint(p2, f)

	e.r.Add(p1, p2)
}

// mapToPoint implements MAP from Section 3.2.4 of draft-hdevalence-cfrg-ristretto-00.
func mapToPoint(out *edwards25519.ExtendedGroupElement, t *radix51.FieldElement) {
	// r = SQRT_M1 * t^2
	r := &radix51.FieldElement{}
	r.Mul(sqrtM1, r.Square(t))

	// u = (r + 1) * ONE_MINUS_D_SQ
	u := &radix51.FieldElement{}
	u.Mul(u.Add(r, radix51.One), oneMinusDSQ)

	// c = -1
	c := &radix51.FieldElement{}
	c.Set(radix51.MinusOne)

	// v = (c - r*D) * (r + D)
	rPlusD := &radix51.FieldElement{}
	rPlusD.Add(r, edwards25519.D)
	v := &radix51.FieldElement{}
	v.Mul(v.Sub(c, v.Mul(r, edwards25519.D)), rPlusD)

	// (was_square, s) = SQRT_RATIO_M1(u, v)
	s := &radix51.FieldElement{}
	wasSquare := feSqrtRatio(s, u, v)

	// s_prime = -CT_ABS(s*t)
	sPrime := &radix51.FieldElement{}
	sPrime.Neg(sPrime.Abs(sPrime.Mul(s, t)))

	// s = CT_SELECT(s IF was_square ELSE s_prime)
	s.Select(s, sPrime, wasSquare)
	// c = CT_SELECT(c IF was_square ELSE r)
	c.Select(c, r, wasSquare)

	// N = c * (r - 1) * D_MINUS_ONE_SQ - v
	N := &radix51.FieldElement{}
	N.Mul(c, N.Sub(r, radix51.One))
	N.Sub(N.Mul(N, dMinusOneSQ), v)

	s2 := &radix51.FieldElement{}
	s2.Square(s)

	// w0 = 2 * s * v
	w0 := &radix51.FieldElement{}
	w0.Add(w0, w0.Mul(s, v))
	// w1 = N * SQRT_AD_MINUS_ONE
	w1 := &radix51.FieldElement{}
	w1.Mul(N, sqrtADMinusOne)
	// w2 = 1 - s^2
	w2 := &radix51.FieldElement{}
	w2.Sub(radix51.One, s2)
	// w3 = 1 + s^2
	w3 := &radix51.FieldElement{}
	w3.Add(radix51.One, s2)

	// return (w0*w3, w2*w1, w1*w3, w0*w2)
	out.X.Mul(w0, w3)
	out.Y.Mul(w2, w1)
	out.Z.Mul(w1, w3)
	out.T.Mul(w0, w2)
}

// Encode encodes a Ristretto group element to its canonical bytestring.
func (ee *Element) Encode() []byte {
	tmp := &radix51.FieldElement{}

	// u1 = (z0 + y0) * (z0 - y0)
	u1 := &radix51.FieldElement{}
	u1.Add(&ee.r.Z, &ee.r.Y).Mul(u1, tmp.Sub(&ee.r.Z, &ee.r.Y))

	// u2 = x0 * y0
	u2 := &radix51.FieldElement{}
	u2.Mul(&ee.r.X, &ee.r.Y)

	// Ignore was_square since this is always square
	// (_, invsqrt) = SQRT_RATIO_M1(1, u1 * u2^2)
	invSqrt := &radix51.FieldElement{}
	_ = feSqrtRatio(invSqrt, u1, tmp.Square(u2))

	// den1 = invsqrt * u1
	// den2 = invsqrt * u2
	// z_inv = den1 * den2 * t0
	den1, den2 := &radix51.FieldElement{}, &radix51.FieldElement{}
	zInv := &radix51.FieldElement{}
	den1.Mul(invSqrt, u1)
	den2.Mul(invSqrt, u2)
	zInv.Mul(den1, den2).Mul(zInv, &ee.r.T)

	// ix0 = x0 * SQRT_M1
	// iy0 = y0 * SQRT_M1
	// enchanted_denominator = den1 * INVSQRT_A_MINUS_D
	ix0, iy0 := &radix51.FieldElement{}, &radix51.FieldElement{}
	enchantedDenominator := &radix51.FieldElement{}
	ix0.Mul(&ee.r.X, sqrtM1)
	iy0.Mul(&ee.r.Y, sqrtM1)
	enchantedDenominator.Mul(den1, invSqrtAMinusD)

	// rotate = IS_NEGATIVE(t0 * z_inv)
	rotate := tmp.Mul(&ee.r.T, zInv).IsNegative()

	// x = CT_SELECT(iy0 IF rotate ELSE x0)
	// y = CT_SELECT(ix0 IF rotate ELSE y0)
	// z = z0
	// den_inv = CT_SELECT(enchanted_denominator IF rotate ELSE den2)
	x, y := &radix51.FieldElement{}, &radix51.FieldElement{}
	denInv := &radix51.FieldElement{}
	x.Select(iy0, &ee.r.X, rotate)
	y.Select(ix0, &ee.r.Y, rotate)
	z := &ee.r.Z
	denInv.Select(enchantedDenominator, den2, rotate)

	// y = CT_NEG(y, IS_NEGATIVE(x * z_inv))
	y.CondNeg(y, tmp.Mul(x, zInv).IsNegative())

	// s = CT_ABS(den_inv * (z - y))
	s := tmp.Mul(denInv, tmp.Sub(z, y)).Abs(tmp)

	// Return the canonical little-endian encoding of s.
	return s.Bytes(nil)
}

// Decode decodes the canonical bytestring encoding of an element into a Ristretto element.
// Returns nil on success.
func (e *Element) Decode(in []byte) error {
	if len(in) != 32 {
		return errInvalidEncoding
	}

	// First, interpret the string as an integer s in little-endian representation.
	s := &radix51.FieldElement{}
	s.FromBytes(in)

	// If the resulting value is >= p, decoding fails.
	// If IS_NEGATIVE(s) returns TRUE, decoding fails.
	if !feMinimal(s) || s.IsNegative() == 1 {
		return errInvalidEncoding
	}

	// ss = s^2
	sSqr := &radix51.FieldElement{}
	sSqr.Square(s)

	// u1 = 1 - ss
	u1 := &radix51.FieldElement{}
	u1.Sub(radix51.One, sSqr)

	// u2 = 1 + ss
	u2 := &radix51.FieldElement{}
	u2.Add(radix51.One, sSqr)

	// u2_sqr = u2^2
	u2Sqr := &radix51.FieldElement{}
	u2Sqr.Square(u2)

	// v = -(D * u1^2) - u2_sqr
	v := &radix51.FieldElement{}
	v.Square(u1).Mul(v, edwards25519.D).Neg(v).Sub(v, u2Sqr)

	// (was_square, invsqrt) = SQRT_RATIO_M1(1, v * u2_sqr)
	invSqrt, tmp := &radix51.FieldElement{}, &radix51.FieldElement{}
	wasSquare := feSqrtRatio(invSqrt, radix51.One, tmp.Mul(v, u2Sqr))

	// den_x = invsqrt * u2
	// den_y = invsqrt * den_x * v
	denX, denY := &radix51.FieldElement{}, &radix51.FieldElement{}
	denX.Mul(invSqrt, u2)
	denY.Mul(invSqrt, denX).Mul(denY, v)

	// x = CT_ABS(2 * s * den_x)
	// y = u1 * den_y
	// t = x * y
	out := &e.r
	out.X.Mul(radix51.Two, s).Mul(&out.X, denX).Abs(&out.X)
	out.Y.Mul(u1, denY)
	out.Z.One()
	out.T.Mul(&out.X, &out.Y)

	// If was_square is FALSE, or IS_NEGATIVE(t) returns TRUE, or y = 0, decoding fails.
	if wasSquare == 0 || out.T.IsNegative() == 1 || out.Y.Equal(radix51.Zero) == 1 {
		return errInvalidEncoding
	}

	// Otherwise, return the internal representation in extended coordinates (x, y, 1, t).
	return nil
}

// Add sets v = p + q, and returns v.
func (v *Element) Add(p, q *Element) *Element {
	v.r.Add(&p.r, &q.r)
	return v
}

// Sub sets v = p - q, and returns v.
func (v *Element) Sub(p, q *Element) *Element {
	v.r.Sub(&p.r, &q.r)
	return v
}

// Neg sets v = -p, and returns v.
func (v *Element) Neg(p *Element) *Element {
	v.r.Neg(&p.r)
	return v
}
<|endoftext|>