<commit_before>package beanstalk

import (
	"fmt"
	"io"
	"net"
	"net/textproto"
	"strings"
	"time"
)

// A Conn represents a connection to a beanstalkd server. It consists
// of a default Tube and TubeSet as well as the underlying network
// connection. The embedded types carry methods with them; see the
// documentation of those types for details.
type Conn struct {
	c       *textproto.Conn
	used    string
	watched map[string]bool
	Tube
	TubeSet
}

var (
	space      = []byte{' '}
	crnl       = []byte{'\r', '\n'}
	yamlHead   = []byte{'-', '-', '-', '\n'}
	nl         = []byte{'\n'}
	colonSpace = []byte{':', ' '}
	minusSpace = []byte{'-', ' '}
)

// NewConn returns a new Conn using conn for I/O.
func NewConn(conn io.ReadWriteCloser) *Conn {
	c := new(Conn)
	c.c = textproto.NewConn(conn)
	c.Tube = Tube{c, "default"}
	c.TubeSet = *NewTubeSet(c, "default")
	c.used = "default"
	c.watched = map[string]bool{"default": true}
	return c
}

// Dial connects to the given address on the given network using net.Dial
// and then returns a new Conn for the connection.
func Dial(network, addr string) (*Conn, error) {
	c, err := net.Dial(network, addr)
	if err != nil {
		return nil, err
	}
	return NewConn(c), nil
}

// Close closes the underlying network connection.
func (c *Conn) Close() error {
	return c.c.Close()
}

func (c *Conn) cmd(t *Tube, ts *TubeSet, body []byte, op string, args ...interface{}) (req, error) {
	r := req{c.c.Next(), op}
	c.c.StartRequest(r.id)
	err := c.adjustTubes(t, ts)
	if err != nil {
		return req{}, err
	}
	if body != nil {
		args = append(args, len(body))
	}
	c.printLine(string(op), args...)
	if body != nil {
		c.c.W.Write(body)
		c.c.W.Write(crnl)
	}
	err = c.c.W.Flush()
	if err != nil {
		return req{}, ConnError{c, op, err}
	}
	c.c.EndRequest(r.id)
	return r, nil
}

func (c *Conn) adjustTubes(t *Tube, ts *TubeSet) error {
	if t != nil && t.Name != c.used {
		if err := checkName(t.Name); err != nil {
			return err
		}
		c.printLine("use", t.Name)
		c.used = t.Name
	}
	if ts != nil {
		for s := range ts.Name {
			if !c.watched[s] {
				if err := checkName(s); err != nil {
					return err
				}
				c.printLine("watch", s)
			}
		}
		for s := range c.watched {
			if !ts.Name[s] {
				c.printLine("ignore", s)
			}
		}
		c.watched = make(map[string]bool)
		for s := range ts.Name {
			c.watched[s] = true
		}
	}
	return nil
}

// does not flush
func (c *Conn) printLine(cmd string, args ...interface{}) {
	io.WriteString(c.c.W, cmd)
	for _, a := range args {
		c.c.W.Write(space)
		fmt.Fprint(c.c.W, a)
	}
	c.c.W.Write(crnl)
}

func (c *Conn) readResp(r req, readBody bool, f string, a ...interface{}) (body []byte, err error) {
	c.c.StartResponse(r.id)
	defer c.c.EndResponse(r.id)
	line, err := c.c.ReadLine()
	for strings.HasPrefix(line, "WATCHING ") || strings.HasPrefix(line, "USING ") {
		line, err = c.c.ReadLine()
	}
	if err != nil {
		return nil, ConnError{c, r.op, err}
	}
	toScan := line
	if readBody {
		var size int
		toScan, size, err = parseSize(toScan)
		if err != nil {
			return nil, ConnError{c, r.op, err}
		}
		body = make([]byte, size+2) // include trailing CR NL
		_, err = io.ReadFull(c.c.R, body)
		if err != nil {
			return nil, ConnError{c, r.op, err}
		}
		body = body[:size] // exclude trailing CR NL
	}

	err = scan(toScan, f, a...)
	if err != nil {
		return nil, ConnError{c, r.op, err}
	}
	return body, nil
}

// Delete deletes the given job id.
func (c *Conn) Delete(id uint64) error {
	r, err := c.cmd(nil, nil, nil, "delete", id)
	if err != nil {
		return err
	}
	_, err = c.readResp(r, false, "DELETED")
	return err
}

// Release sets the priotiry of job id to pri, removes it from the list
// of jobs reserved by the client c, waits delay seconds, then places
// the job in the ready queue, thus making it available for reservation
// by any client. Calls to Release return before the delay period.
func (c *Conn) Release(id uint64, pri uint32, delay time.Duration) error {
	r, err := c.cmd(nil, nil, nil, "release", id, pri, dur(delay))
	if err != nil {
		return err
	}
	_, err = c.readResp(r, false, "RELEASED")
	return err
}

// Bury places the given job id in a holding area in the job's tube and
// sets its priority to pri. The job will not be scheduled again until it
// has been kicked; see also the documentation of Kick.
func (c *Conn) Bury(id uint64, pri uint32) error {
	r, err := c.cmd(nil, nil, nil, "bury", id, pri)
	if err != nil {
		return err
	}
	_, err = c.readResp(r, false, "BURIED")
	return err
}

// Touch resets the reservation timeout for job id to the job's TTR.
// It is an error if the job isn't currently reserved by c.
// See the documentation of Reserve for more details.
func (c *Conn) Touch(id uint64) error {
	r, err := c.cmd(nil, nil, nil, "touch", id)
	if err != nil {
		return err
	}
	_, err = c.readResp(r, false, "TOUCHED")
	return err
}

// Peek gets a copy of job id from the server.
func (c *Conn) Peek(id uint64) (body []byte, err error) {
	r, err := c.cmd(nil, nil, nil, "peek", id)
	if err != nil {
		return nil, err
	}
	return c.readResp(r, true, "FOUND %d", &id)
}

// Stats retrieves global statistics from the server.
func (c *Conn) Stats() (map[string]string, error) {
	r, err := c.cmd(nil, nil, nil, "stats")
	if err != nil {
		return nil, err
	}
	body, err := c.readResp(r, true, "OK")
	return parseDict(body), err
}

// StatsJob retrieves statistics about job id.
func (c *Conn) StatsJob(id uint64) (map[string]string, error) {
	r, err := c.cmd(nil, nil, nil, "stats-job", id)
	if err != nil {
		return nil, err
	}
	body, err := c.readResp(r, true, "OK")
	return parseDict(body), err
}

// ListTubes returns a slice of the names of the tubes that currently
// exist on the server.
func (c *Conn) ListTubes() ([]string, error) {
	r, err := c.cmd(nil, nil, nil, "list-tubes")
	if err != nil {
		return nil, err
	}
	body, err := c.readResp(r, true, "OK")
	return parseList(body), err
}

func scan(input, format string, a ...interface{}) error {
	_, err := fmt.Sscanf(input, format, a...)
	if err != nil {
		err = respError[input]
		if err != nil {
			return err
		}
		return unknownRespError(input)
	}
	return nil
}

type req struct {
	id uint
	op string
}
<commit_msg>reword<commit_after>package beanstalk

import (
	"fmt"
	"io"
	"net"
	"net/textproto"
	"strings"
	"time"
)

// A Conn represents a connection to a beanstalkd server. It consists
// of a default Tube and TubeSet as well as the underlying network
// connection. The embedded types carry methods with them; see the
// documentation of those types for details.
type Conn struct {
	c       *textproto.Conn
	used    string
	watched map[string]bool
	Tube
	TubeSet
}

var (
	space      = []byte{' '}
	crnl       = []byte{'\r', '\n'}
	yamlHead   = []byte{'-', '-', '-', '\n'}
	nl         = []byte{'\n'}
	colonSpace = []byte{':', ' '}
	minusSpace = []byte{'-', ' '}
)

// NewConn returns a new Conn using conn for I/O.
func NewConn(conn io.ReadWriteCloser) *Conn {
	c := new(Conn)
	c.c = textproto.NewConn(conn)
	c.Tube = Tube{c, "default"}
	c.TubeSet = *NewTubeSet(c, "default")
	c.used = "default"
	c.watched = map[string]bool{"default": true}
	return c
}

// Dial connects to the given address on the given network using net.Dial
// and then returns a new Conn for the connection.
func Dial(network, addr string) (*Conn, error) {
	c, err := net.Dial(network, addr)
	if err != nil {
		return nil, err
	}
	return NewConn(c), nil
}

// Close closes the underlying network connection.
func (c *Conn) Close() error {
	return c.c.Close()
}

func (c *Conn) cmd(t *Tube, ts *TubeSet, body []byte, op string, args ...interface{}) (req, error) {
	r := req{c.c.Next(), op}
	c.c.StartRequest(r.id)
	err := c.adjustTubes(t, ts)
	if err != nil {
		return req{}, err
	}
	if body != nil {
		args = append(args, len(body))
	}
	c.printLine(string(op), args...)
	if body != nil {
		c.c.W.Write(body)
		c.c.W.Write(crnl)
	}
	err = c.c.W.Flush()
	if err != nil {
		return req{}, ConnError{c, op, err}
	}
	c.c.EndRequest(r.id)
	return r, nil
}

func (c *Conn) adjustTubes(t *Tube, ts *TubeSet) error {
	if t != nil && t.Name != c.used {
		if err := checkName(t.Name); err != nil {
			return err
		}
		c.printLine("use", t.Name)
		c.used = t.Name
	}
	if ts != nil {
		for s := range ts.Name {
			if !c.watched[s] {
				if err := checkName(s); err != nil {
					return err
				}
				c.printLine("watch", s)
			}
		}
		for s := range c.watched {
			if !ts.Name[s] {
				c.printLine("ignore", s)
			}
		}
		c.watched = make(map[string]bool)
		for s := range ts.Name {
			c.watched[s] = true
		}
	}
	return nil
}

// does not flush
func (c *Conn) printLine(cmd string, args ...interface{}) {
	io.WriteString(c.c.W, cmd)
	for _, a := range args {
		c.c.W.Write(space)
		fmt.Fprint(c.c.W, a)
	}
	c.c.W.Write(crnl)
}

func (c *Conn) readResp(r req, readBody bool, f string, a ...interface{}) (body []byte, err error) {
	c.c.StartResponse(r.id)
	defer c.c.EndResponse(r.id)
	line, err := c.c.ReadLine()
	for strings.HasPrefix(line, "WATCHING ") || strings.HasPrefix(line, "USING ") {
		line, err = c.c.ReadLine()
	}
	if err != nil {
		return nil, ConnError{c, r.op, err}
	}
	toScan := line
	if readBody {
		var size int
		toScan, size, err = parseSize(toScan)
		if err != nil {
			return nil, ConnError{c, r.op, err}
		}
		body = make([]byte, size+2) // include trailing CR NL
		_, err = io.ReadFull(c.c.R, body)
		if err != nil {
			return nil, ConnError{c, r.op, err}
		}
		body = body[:size] // exclude trailing CR NL
	}

	err = scan(toScan, f, a...)
	if err != nil {
		return nil, ConnError{c, r.op, err}
	}
	return body, nil
}

// Delete deletes the given job.
func (c *Conn) Delete(id uint64) error {
	r, err := c.cmd(nil, nil, nil, "delete", id)
	if err != nil {
		return err
	}
	_, err = c.readResp(r, false, "DELETED")
	return err
}

// Release tells the server to perform the following actions:
// set the priority of the given job to pri, remove it from the list of
// jobs reserved by c, wait delay seconds, then place the job in the
// ready queue, which makes it available for reservation by any client.
func (c *Conn) Release(id uint64, pri uint32, delay time.Duration) error {
	r, err := c.cmd(nil, nil, nil, "release", id, pri, dur(delay))
	if err != nil {
		return err
	}
	_, err = c.readResp(r, false, "RELEASED")
	return err
}

// Bury places the given job in a holding area in the job's tube and
// sets its priority to pri. The job will not be scheduled again until it
// has been kicked; see also the documentation of Kick.
func (c *Conn) Bury(id uint64, pri uint32) error {
	r, err := c.cmd(nil, nil, nil, "bury", id, pri)
	if err != nil {
		return err
	}
	_, err = c.readResp(r, false, "BURIED")
	return err
}

// Touch resets the reservation timer for the given job.
// It is an error if the job isn't currently reserved by c.
// See the documentation of Reserve for more details.
func (c *Conn) Touch(id uint64) error {
	r, err := c.cmd(nil, nil, nil, "touch", id)
	if err != nil {
		return err
	}
	_, err = c.readResp(r, false, "TOUCHED")
	return err
}

// Peek gets a copy of the specified job from the server.
func (c *Conn) Peek(id uint64) (body []byte, err error) {
	r, err := c.cmd(nil, nil, nil, "peek", id)
	if err != nil {
		return nil, err
	}
	return c.readResp(r, true, "FOUND %d", &id)
}

// Stats retrieves global statistics from the server.
func (c *Conn) Stats() (map[string]string, error) {
	r, err := c.cmd(nil, nil, nil, "stats")
	if err != nil {
		return nil, err
	}
	body, err := c.readResp(r, true, "OK")
	return parseDict(body), err
}

// StatsJob retrieves statistics about the given job.
func (c *Conn) StatsJob(id uint64) (map[string]string, error) {
	r, err := c.cmd(nil, nil, nil, "stats-job", id)
	if err != nil {
		return nil, err
	}
	body, err := c.readResp(r, true, "OK")
	return parseDict(body), err
}

// ListTubes returns the names of the tubes that currently
// exist on the server.
func (c *Conn) ListTubes() ([]string, error) {
	r, err := c.cmd(nil, nil, nil, "list-tubes")
	if err != nil {
		return nil, err
	}
	body, err := c.readResp(r, true, "OK")
	return parseList(body), err
}

func scan(input, format string, a ...interface{}) error {
	_, err := fmt.Sscanf(input, format, a...)
	if err != nil {
		err = respError[input]
		if err != nil {
			return err
		}
		return unknownRespError(input)
	}
	return nil
}

type req struct {
	id uint
	op string
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/csv"
	"fmt"
	"io"
	"os"
	"strings"
)

func main() {
	if len(os.Args) < 3 {
		fmt.Println("Usage: csvv CSV-FILE col1[,col2,col3 ...]")
		return
	}

	csvfile, err := os.Open(os.Args[1])
	if err != nil {
		fmt.Println(err)
		return
	}

	defer csvfile.Close()
	reader := csv.NewReader(csvfile)

	// Get all headers. assuming the first line is header line
	row, err := reader.Read()
	if err != nil {
		fmt.Println(err)
	}
	var h map[string]int = map[string]int{}
	for index, name := range row {
		h[name] = index
	}

	// Parse 2nd argument to determine which columns need to be got
	var cols []string
	for _, c := range strings.Split(os.Args[2], ",") {
		if _, ok := h[c]; ok {
			cols = append(cols, c)
		}
	}

	// header
	PrintCSV(cols)

	// Parse body
	for {
		rec, err := reader.Read()
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Println(err)
			return
		}

		var line []string
		for _, col := range cols {
			if _, ok := h[col]; ok {
				line = append(line, rec[h[col]])
			}
		}
		PrintCSV(line)
	}
}

func Pos(sl []string, v string) int {
	for index, value := range sl {
		if value == v {
			return index
		}
	}
	return -1
}

func PrintCSV(cols []string) {
	fmt.Println(strings.Join(cols, ","))
}
<commit_msg>Add license statement<commit_after>// csvv - A simple CSV extractor.
// Author: Takahiro Yoshihara <tacahiroy@gmail.com>
// License: Modified BSD License

// Copyright © 2016 Takahiro Yoshihara
// All rights reserved.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the organization nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY  "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL  BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package main

import (
	"encoding/csv"
	"fmt"
	"io"
	"os"
	"strings"
)

func printCSV(cols []string) {
	fmt.Println(strings.Join(cols, ","))
}

func main() {
	if len(os.Args) < 3 {
		fmt.Println("Usage: csvv CSV-FILE col1[,col2,col3 ...]")
		return
	}

	csvfile, err := os.Open(os.Args[1])
	if err != nil {
		fmt.Println(err)
		return
	}

	defer csvfile.Close()
	reader := csv.NewReader(csvfile)

	// Get all headers. assuming the first line is header line
	row, err := reader.Read()
	if err != nil {
		fmt.Println(err)
	}
	var h map[string]int = map[string]int{}
	for index, name := range row {
		h[name] = index
	}

	// Parse 2nd argument to determine which columns need to be got
	var cols []string
	for _, c := range strings.Split(os.Args[2], ",") {
		if _, ok := h[c]; ok {
			cols = append(cols, c)
		}
	}

	// header
	printCSV(cols)

	// Parse body
	for {
		rec, err := reader.Read()
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Println(err)
			return
		}

		var line []string
		for _, col := range cols {
			if _, ok := h[col]; ok {
				line = append(line, rec[h[col]])
			}
		}
		printCSV(line)
	}
}
<|endoftext|>


<commit_before>package conf

import (
	"log"
	"os"
)

var consoleLog = log.New(os.Stdout, "[conf] ", log.LstdFlags)
var DEBUG bool = false

type Config interface {
	Get(section, name string) string
	GetInt(section, name string) int
	Set(section, name, value string)
	GetSection(section string) []SectionConfig
	Reload() error
}

type SectionConfig interface {
	Get(name string) string
	GetInt(name string) int
	Set(name, value string)
}
<commit_msg>drop space line<commit_after>/*
Package conf is to provide a config, such as ini, json, xml etc.
*/
package conf

import (
	"log"
	"os"
)

var consoleLog = log.New(os.Stdout, "[conf] ", log.LstdFlags)

// DEBUG is switcher for debug
var DEBUG = false

// Config is an interface for config
type Config interface {
	// Get value
	Get(section, name string) string
	// GetInt is to get interger value
	GetInt(section, name string) int
	// Set value
	Set(section, name, value string)
	// GetSection is to get section
	GetSection(section string) []SectionConfig
	// Reload config
	Reload() error
}

// SectionConfig is section part for config
type SectionConfig interface {
	// Get value
	Get(name string) string
	//GetInt is to get interger value
	GetInt(name string) int
	// Set value
	Set(name, value string)
}
<|endoftext|>


<commit_before>// Copyright (c) Liam Stanley <me@liamstanley.io>. All rights reserved. Use
// of this source code is governed by the MIT license that can be found in
// the LICENSE file.

package girc

import (
	"bufio"
	"io"
	"sync"
)

// Messages are delimited with CR and LF line endings, we're using the last
// one to split the stream. Both are removed during parsing of the message.
const delim byte = '\n'

var endline = []byte("\r\n")

// ircConn represents an IRC network protocol connection, it consists of an
// Encoder and Decoder to manage i/o.
type ircConn struct {
	ircEncoder
	ircDecoder

	c io.ReadWriteCloser
}

// Close closes the underlying ReadWriteCloser.
func (c *ircConn) Close() error {
	return c.c.Close()
}

// ircDecoder reads Event objects from an input stream.
type ircDecoder struct {
	reader *bufio.Reader
	line   string
	mu     sync.Mutex
}

// newDecoder returns a new Decoder that reads from r.
func newDecoder(r io.Reader) *ircDecoder {
	return &ircDecoder{reader: bufio.NewReader(r)}
}

// Decode attempts to read a single Event from the stream, returns non-nil
// error if read failed.
func (dec *ircDecoder) Decode() (e *Event, err error) {
	dec.mu.Lock()
	dec.line, err = dec.reader.ReadString(delim)
	dec.mu.Unlock()

	if err != nil {
		return nil, err
	}

	return ParseEvent(dec.line), nil
}

// ircEncoder writes Event objects to an output stream.
type ircEncoder struct {
	writer io.Writer
	mu     sync.Mutex
}

// newEncoder returns a new Encoder that writes to w.
func newEncoder(w io.Writer) *ircEncoder {
	return &ircEncoder{writer: w}
}

// Encode writes the IRC encoding of m to the stream. Goroutine safe.
// returns non-nil error if the write to the underlying stream stopped early.
func (enc *ircEncoder) Encode(e *Event) (err error) {
	_, err = enc.Write(e.Bytes())

	return
}

// Write writes len(p) bytes from p followed by CR+LF. Goroutine safe.
func (enc *ircEncoder) Write(p []byte) (n int, err error) {
	enc.mu.Lock()
	defer enc.mu.Unlock()

	n, err = enc.writer.Write(p)
	if err != nil {
		return
	}

	_, err = enc.writer.Write(endline)

	return
}
<commit_msg>better description if returned results<commit_after>// Copyright (c) Liam Stanley <me@liamstanley.io>. All rights reserved. Use
// of this source code is governed by the MIT license that can be found in
// the LICENSE file.

package girc

import (
	"bufio"
	"io"
	"sync"
)

// Messages are delimited with CR and LF line endings, we're using the last
// one to split the stream. Both are removed during parsing of the message.
const delim byte = '\n'

var endline = []byte("\r\n")

// ircConn represents an IRC network protocol connection, it consists of an
// Encoder and Decoder to manage i/o.
type ircConn struct {
	ircEncoder
	ircDecoder

	c io.ReadWriteCloser
}

// Close closes the underlying ReadWriteCloser.
func (c *ircConn) Close() error {
	return c.c.Close()
}

// ircDecoder reads Event objects from an input stream.
type ircDecoder struct {
	reader *bufio.Reader
	line   string
	mu     sync.Mutex
}

// newDecoder returns a new Decoder that reads from r.
func newDecoder(r io.Reader) *ircDecoder {
	return &ircDecoder{reader: bufio.NewReader(r)}
}

// Decode attempts to read a single Event from the stream, returns non-nil
// error if read failed. event may be nil if unparseable.
func (dec *ircDecoder) Decode() (event *Event, err error) {
	dec.mu.Lock()
	dec.line, err = dec.reader.ReadString(delim)
	dec.mu.Unlock()

	if err != nil {
		return nil, err
	}

	return ParseEvent(dec.line), nil
}

// ircEncoder writes Event objects to an output stream.
type ircEncoder struct {
	writer io.Writer
	mu     sync.Mutex
}

// newEncoder returns a new Encoder that writes to w.
func newEncoder(w io.Writer) *ircEncoder {
	return &ircEncoder{writer: w}
}

// Encode writes the IRC encoding of m to the stream. Goroutine safe.
// returns non-nil error if the write to the underlying stream stopped early.
func (enc *ircEncoder) Encode(e *Event) (err error) {
	_, err = enc.Write(e.Bytes())

	return
}

// Write writes len(p) bytes from p followed by CR+LF. Goroutine safe.
func (enc *ircEncoder) Write(p []byte) (n int, err error) {
	enc.mu.Lock()
	defer enc.mu.Unlock()

	n, err = enc.writer.Write(p)
	if err != nil {
		return
	}

	_, err = enc.writer.Write(endline)

	return
}
<|endoftext|>


<commit_before>package utp

/*
#include "utp.h"
*/
import "C"
import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"net"
	"sync"
	"syscall"
	"time"
	"unsafe"
)

var (
	ErrConnClosed    = errors.New("closed")
	errConnDestroyed = errors.New("destroyed")
)

type Conn struct {
	s          *Socket
	us         *C.utp_socket
	cond       sync.Cond
	readBuf    bytes.Buffer
	gotEOF     bool
	gotConnect bool
	// Set on state changed to UTP_STATE_DESTROYING. Not valid to refer to the
	// socket after getting this.
	destroyed bool
	// Conn.Close was called.
	closed bool
	// Corresponds to utp_socket.state != CS_UNITIALIZED. This requires the
	// utp_socket was obtained from the accept callback, or has had
	// utp_connect called on it. We can't call utp_close until it's true.
	inited bool

	err error

	writeDeadline      time.Time
	writeDeadlineTimer *time.Timer
	readDeadline       time.Time
	readDeadlineTimer  *time.Timer

	numBytesRead    int64
	numBytesWritten int64

	localAddr  net.Addr
	remoteAddr net.Addr

	// Called for non-fatal errors, such as packet write errors.
	userOnError func(error)
}

func (c *Conn) onError(err error) {
	c.err = err
	c.cond.Broadcast()
}

func (c *Conn) setConnected() {
	c.gotConnect = true
	c.cond.Broadcast()
}

func (c *Conn) waitForConnect(ctx context.Context) error {
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()
	go func() {
		<-ctx.Done()
		c.cond.Broadcast()
	}()
	for {
		if c.closed {
			return ErrConnClosed
		}
		if c.err != nil {
			return c.err
		}
		if c.gotConnect {
			return nil
		}
		if ctx.Err() != nil {
			return ctx.Err()
		}
		c.cond.Wait()
	}
}

func (c *Conn) Close() error {
	mu.Lock()
	defer mu.Unlock()
	c.close()
	return nil
}

func (c *Conn) close() {
	if c.inited && !c.destroyed && !c.closed {
		C.utp_close(c.us)
	}
	if !c.inited {
		// We'll never receive a destroy message, so we should remove it now.
		delete(c.s.conns, c.us)
	}
	c.closed = true
	c.cond.Broadcast()
}

func (c *Conn) LocalAddr() net.Addr {
	return c.localAddr
}

func (c *Conn) readNoWait(b []byte) (n int, err error) {
	n, _ = c.readBuf.Read(b)
	if n != 0 && c.readBuf.Len() == 0 {
		// Can we call this if the utp_socket is closed, destroyed or errored?
		if c.us != nil {
			C.utp_read_drained(c.us)
			// C.utp_issue_deferred_acks(C.utp_get_context(c.s))
		}
	}
	if c.readBuf.Len() != 0 {
		return
	}
	err = func() error {
		switch {
		case c.gotEOF:
			return io.EOF
		case c.err != nil:
			return c.err
		case c.destroyed:
			return errConnDestroyed
		case c.closed:
			return errors.New("closed")
		case !c.readDeadline.IsZero() && !time.Now().Before(c.readDeadline):
			return errDeadlineExceeded{}
		default:
			return nil
		}
	}()
	return
}

func (c *Conn) Read(b []byte) (int, error) {
	mu.Lock()
	defer mu.Unlock()
	for {
		n, err := c.readNoWait(b)
		c.numBytesRead += int64(n)
		// log.Printf("read %d bytes", c.numBytesRead)
		if n != 0 || len(b) == 0 || err != nil {
			// log.Printf("conn %p: read %d bytes: %s", c, n, err)
			return n, err
		}
		c.cond.Wait()
	}
}

func (c *Conn) writeNoWait(b []byte) (n int, err error) {
	err = func() error {
		switch {
		case c.err != nil:
			return c.err
		case c.closed:
			return ErrConnClosed
		case c.destroyed:
			return errConnDestroyed
		case !c.writeDeadline.IsZero() && !time.Now().Before(c.writeDeadline):
			return errDeadlineExceeded{}
		default:
			return nil
		}
	}()
	if err != nil {
		return
	}
	n = int(C.utp_write(c.us, unsafe.Pointer(&b[0]), C.size_t(len(b))))
	if n < 0 {
		panic(n)
	}
	return
}

func (c *Conn) Write(b []byte) (n int, err error) {
	mu.Lock()
	defer mu.Unlock()
	for len(b) != 0 {
		var n1 int
		n1, err = c.writeNoWait(b)
		b = b[n1:]
		n += n1
		if err != nil {
			break
		}
		if n1 != 0 {
			continue
		}
		c.cond.Wait()
	}
	c.numBytesWritten += int64(n)
	// log.Printf("wrote %d bytes", c.numBytesWritten)
	return
}

func (c *Conn) setRemoteAddr() {
	var rsa syscall.RawSockaddrAny
	var addrlen C.socklen_t = C.socklen_t(unsafe.Sizeof(rsa))
	C.utp_getpeername(c.us, (*C.struct_sockaddr)(unsafe.Pointer(&rsa)), &addrlen)
	var udp net.UDPAddr
	if err := anySockaddrToUdp(&rsa, &udp); err != nil {
		panic(err)
	}
	c.remoteAddr = &udp
}

func (c *Conn) RemoteAddr() net.Addr {
	return c.remoteAddr
}

func (c *Conn) SetDeadline(t time.Time) error {
	mu.Lock()
	defer mu.Unlock()
	c.readDeadline = t
	c.writeDeadline = t
	if t.IsZero() {
		c.readDeadlineTimer.Stop()
		c.writeDeadlineTimer.Stop()
	} else {
		d := t.Sub(time.Now())
		c.readDeadlineTimer.Reset(d)
		c.writeDeadlineTimer.Reset(d)
	}
	c.cond.Broadcast()
	return nil
}
func (c *Conn) SetReadDeadline(t time.Time) error {
	mu.Lock()
	defer mu.Unlock()
	c.readDeadline = t
	if t.IsZero() {
		c.readDeadlineTimer.Stop()
	} else {
		d := t.Sub(time.Now())
		c.readDeadlineTimer.Reset(d)
	}
	c.cond.Broadcast()
	return nil
}
func (c *Conn) SetWriteDeadline(t time.Time) error {
	mu.Lock()
	defer mu.Unlock()
	c.writeDeadline = t
	if t.IsZero() {
		c.writeDeadlineTimer.Stop()
	} else {
		d := t.Sub(time.Now())
		c.writeDeadlineTimer.Reset(d)
	}
	c.cond.Broadcast()
	return nil
}

func (c *Conn) setGotEOF() {
	c.gotEOF = true
	c.cond.Broadcast()
}

func (c *Conn) onDestroyed() {
	c.destroyed = true
	c.us = nil
	c.cond.Broadcast()
}

func (c *Conn) WriteBufferLen() int {
	mu.Lock()
	defer mu.Unlock()
	return int(C.utp_getsockopt(c.us, C.UTP_SNDBUF))
}

func (c *Conn) SetWriteBufferLen(len int) {
	mu.Lock()
	defer mu.Unlock()
	i := C.utp_setsockopt(c.us, C.UTP_SNDBUF, C.int(len))
	if i != 0 {
		panic(i)
	}
}

// Connect an unconnected Conn (obtained through Socket.NewConn).
func (c *Conn) Connect(ctx context.Context, network, addr string) error {
	if network == "" {
		network = c.localAddr.Network()
	}
	ua, err := resolveAddr(network, addr)
	if err != nil {
		return fmt.Errorf("error resolving address: %v", err)
	}
	sa, sl := netAddrToLibSockaddr(ua)
	mu.Lock()
	defer mu.Unlock()
	if c.s.closed {
		return errSocketClosed
	}
	if n := C.utp_connect(c.us, sa, sl); n != 0 {
		panic(n)
	}
	c.inited = true
	c.setRemoteAddr()
	err = c.waitForConnect(ctx)
	if err != nil {
		c.close()
		return err
	}
	return nil
}

func (c *Conn) OnError(f func(error)) {
	mu.Lock()
	c.userOnError = f
	mu.Unlock()
}
<commit_msg>Tidy up some error types<commit_after>package utp

/*
#include "utp.h"
*/
import "C"
import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"net"
	"sync"
	"syscall"
	"time"
	"unsafe"
)

var (
	ErrConnClosed            = errors.New("closed")
	errConnDestroyed         = errors.New("destroyed")
	errDeadlineExceededValue = errDeadlineExceeded{}
)

type Conn struct {
	s          *Socket
	us         *C.utp_socket
	cond       sync.Cond
	readBuf    bytes.Buffer
	gotEOF     bool
	gotConnect bool
	// Set on state changed to UTP_STATE_DESTROYING. Not valid to refer to the
	// socket after getting this.
	destroyed bool
	// Conn.Close was called.
	closed bool
	// Corresponds to utp_socket.state != CS_UNITIALIZED. This requires the
	// utp_socket was obtained from the accept callback, or has had
	// utp_connect called on it. We can't call utp_close until it's true.
	inited bool

	err error

	writeDeadline      time.Time
	writeDeadlineTimer *time.Timer
	readDeadline       time.Time
	readDeadlineTimer  *time.Timer

	numBytesRead    int64
	numBytesWritten int64

	localAddr  net.Addr
	remoteAddr net.Addr

	// Called for non-fatal errors, such as packet write errors.
	userOnError func(error)
}

func (c *Conn) onError(err error) {
	c.err = err
	c.cond.Broadcast()
}

func (c *Conn) setConnected() {
	c.gotConnect = true
	c.cond.Broadcast()
}

func (c *Conn) waitForConnect(ctx context.Context) error {
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()
	go func() {
		<-ctx.Done()
		c.cond.Broadcast()
	}()
	for {
		if c.closed {
			return ErrConnClosed
		}
		if c.err != nil {
			return c.err
		}
		if c.gotConnect {
			return nil
		}
		if ctx.Err() != nil {
			return ctx.Err()
		}
		c.cond.Wait()
	}
}

func (c *Conn) Close() error {
	mu.Lock()
	defer mu.Unlock()
	c.close()
	return nil
}

func (c *Conn) close() {
	if c.inited && !c.destroyed && !c.closed {
		C.utp_close(c.us)
	}
	if !c.inited {
		// We'll never receive a destroy message, so we should remove it now.
		delete(c.s.conns, c.us)
	}
	c.closed = true
	c.cond.Broadcast()
}

func (c *Conn) LocalAddr() net.Addr {
	return c.localAddr
}

func (c *Conn) readNoWait(b []byte) (n int, err error) {
	n, _ = c.readBuf.Read(b)
	if n != 0 && c.readBuf.Len() == 0 {
		// Can we call this if the utp_socket is closed, destroyed or errored?
		if c.us != nil {
			C.utp_read_drained(c.us)
			// C.utp_issue_deferred_acks(C.utp_get_context(c.s))
		}
	}
	if c.readBuf.Len() != 0 {
		return
	}
	err = func() error {
		switch {
		case c.gotEOF:
			return io.EOF
		case c.err != nil:
			return c.err
		case c.destroyed:
			return errConnDestroyed
		case c.closed:
			return ErrConnClosed
		case !c.readDeadline.IsZero() && !time.Now().Before(c.readDeadline):
			return errDeadlineExceededValue
		default:
			return nil
		}
	}()
	return
}

func (c *Conn) Read(b []byte) (int, error) {
	mu.Lock()
	defer mu.Unlock()
	for {
		n, err := c.readNoWait(b)
		c.numBytesRead += int64(n)
		// log.Printf("read %d bytes", c.numBytesRead)
		if n != 0 || len(b) == 0 || err != nil {
			// log.Printf("conn %p: read %d bytes: %s", c, n, err)
			return n, err
		}
		c.cond.Wait()
	}
}

func (c *Conn) writeNoWait(b []byte) (n int, err error) {
	err = func() error {
		switch {
		case c.err != nil:
			return c.err
		case c.closed:
			return ErrConnClosed
		case c.destroyed:
			return errConnDestroyed
		case !c.writeDeadline.IsZero() && !time.Now().Before(c.writeDeadline):
			return errDeadlineExceededValue
		default:
			return nil
		}
	}()
	if err != nil {
		return
	}
	n = int(C.utp_write(c.us, unsafe.Pointer(&b[0]), C.size_t(len(b))))
	if n < 0 {
		panic(n)
	}
	return
}

func (c *Conn) Write(b []byte) (n int, err error) {
	mu.Lock()
	defer mu.Unlock()
	for len(b) != 0 {
		var n1 int
		n1, err = c.writeNoWait(b)
		b = b[n1:]
		n += n1
		if err != nil {
			break
		}
		if n1 != 0 {
			continue
		}
		c.cond.Wait()
	}
	c.numBytesWritten += int64(n)
	// log.Printf("wrote %d bytes", c.numBytesWritten)
	return
}

func (c *Conn) setRemoteAddr() {
	var rsa syscall.RawSockaddrAny
	var addrlen C.socklen_t = C.socklen_t(unsafe.Sizeof(rsa))
	C.utp_getpeername(c.us, (*C.struct_sockaddr)(unsafe.Pointer(&rsa)), &addrlen)
	var udp net.UDPAddr
	if err := anySockaddrToUdp(&rsa, &udp); err != nil {
		panic(err)
	}
	c.remoteAddr = &udp
}

func (c *Conn) RemoteAddr() net.Addr {
	return c.remoteAddr
}

func (c *Conn) SetDeadline(t time.Time) error {
	mu.Lock()
	defer mu.Unlock()
	c.readDeadline = t
	c.writeDeadline = t
	if t.IsZero() {
		c.readDeadlineTimer.Stop()
		c.writeDeadlineTimer.Stop()
	} else {
		d := t.Sub(time.Now())
		c.readDeadlineTimer.Reset(d)
		c.writeDeadlineTimer.Reset(d)
	}
	c.cond.Broadcast()
	return nil
}
func (c *Conn) SetReadDeadline(t time.Time) error {
	mu.Lock()
	defer mu.Unlock()
	c.readDeadline = t
	if t.IsZero() {
		c.readDeadlineTimer.Stop()
	} else {
		d := t.Sub(time.Now())
		c.readDeadlineTimer.Reset(d)
	}
	c.cond.Broadcast()
	return nil
}
func (c *Conn) SetWriteDeadline(t time.Time) error {
	mu.Lock()
	defer mu.Unlock()
	c.writeDeadline = t
	if t.IsZero() {
		c.writeDeadlineTimer.Stop()
	} else {
		d := t.Sub(time.Now())
		c.writeDeadlineTimer.Reset(d)
	}
	c.cond.Broadcast()
	return nil
}

func (c *Conn) setGotEOF() {
	c.gotEOF = true
	c.cond.Broadcast()
}

func (c *Conn) onDestroyed() {
	c.destroyed = true
	c.us = nil
	c.cond.Broadcast()
}

func (c *Conn) WriteBufferLen() int {
	mu.Lock()
	defer mu.Unlock()
	return int(C.utp_getsockopt(c.us, C.UTP_SNDBUF))
}

func (c *Conn) SetWriteBufferLen(len int) {
	mu.Lock()
	defer mu.Unlock()
	i := C.utp_setsockopt(c.us, C.UTP_SNDBUF, C.int(len))
	if i != 0 {
		panic(i)
	}
}

// Connect an unconnected Conn (obtained through Socket.NewConn).
func (c *Conn) Connect(ctx context.Context, network, addr string) error {
	if network == "" {
		network = c.localAddr.Network()
	}
	ua, err := resolveAddr(network, addr)
	if err != nil {
		return fmt.Errorf("error resolving address: %v", err)
	}
	sa, sl := netAddrToLibSockaddr(ua)
	mu.Lock()
	defer mu.Unlock()
	if c.s.closed {
		return errSocketClosed
	}
	if n := C.utp_connect(c.us, sa, sl); n != 0 {
		panic(n)
	}
	c.inited = true
	c.setRemoteAddr()
	err = c.waitForConnect(ctx)
	if err != nil {
		c.close()
		return err
	}
	return nil
}

func (c *Conn) OnError(f func(error)) {
	mu.Lock()
	c.userOnError = f
	mu.Unlock()
}
<|endoftext|>


<commit_before>package rgo

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
)

// Conn is used to start and communicate with an R process. Conn
// is NOT thread-safe. However, you may run multiple Conn's in
// the same process safely. It is safe to run successive
// operations on Conn successively and retrieve any errors
// using Error(). Do not that although R warnings will be
// returned in method calls, they will not be captured in Error().
type Conn struct {
	cmd     *exec.Cmd
	inPipe  io.WriteCloser
	counter uint64
	server  *server

	err    error
	strict bool
	closed bool
}

func (c *Conn) start() error {
	err := c.cmd.Start()
	if err != nil {
		return err
	}
	return err
}

type connConfig struct {
	debug bool
}

type ConnOption func(*connConfig)

func WithDebug() ConnOption {
	return func(c *connConfig) {
		c.debug = true
	}
}

const checkDepsCmd = "cat(is.element(\"jsonlite\", installed.packages()[,1]) & is.element(\"RCurl\", installed.packages()[,1]))\n"

func Connection(opts ...ConnOption) (*Conn, error) {
	var cfg connConfig
	for _, opt := range opts {
		opt(&cfg)
	}
	var c Conn
	out, err := exec.Command("R", "--no-save", "-s", "-e", checkDepsCmd).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("failed to check dependencies: %v", err)
	}
	if string(out) != "TRUE" {
		fmt.Printf("got: %s", out)
		return nil, errors.New("need to install 'jsonlite' and 'RCurl'")
	}
	c.cmd = exec.Command("R", "--no-save")
	c.inPipe, err = c.cmd.StdinPipe()
	if cfg.debug {
		c.cmd.Stdout = os.Stdout
		c.cmd.Stderr = os.Stderr
	}
	if err != nil {
		return nil, err
	}
	err = c.start()
	if err != nil {
		return nil, err
	}
	if err != nil {
		c.Close()
		return nil, err
	}
	c.server, err = newServer()
	if err != nil {
		goto ErrCleanup
	}
	err = c.directR("library(jsonlite)\n")
	if err != nil {
		goto ErrCleanup
	}
	err = c.directR("library(RCurl)\n")
	if err != nil {
		goto ErrCleanup
	}
	runtime.SetFinalizer(&c, func(c *Conn) { c.Close() })
	return &c, nil

ErrCleanup:
	c.Close()
	return nil, err
}

func (c *Conn) Close() error {
	if c.closed {
		return nil
	}
	c.directR("q()")
	c.inPipe.Close()
	err1 := c.cmd.Wait()
	err2 := c.server.s.Stop()
	if err1 != nil {
		return err1
	}
	return err2
}

// directR sends the command to R without trapping errors.
// directR should only be used for registring some internal functions.
func (c *Conn) directR(cmd string) error {
	_, err := io.WriteString(c.inPipe, cmd)
	return err
}

const cmdStr = `..rgo.ret = c("", "")
tryCatch({
	%s
}, warning = function(w) {
	..rgo.ret[1] <<- conditionMessage(w)
}, error = function(e) {
	..rgo.ret[2] <<- conditionMessage(e)
})
print(..rgo.ret)
httpPUT("http://localhost:%d/%s", toJSON(..rgo.ret))
`

type res struct {
	Error   string
	Warning string
	strict  bool
}

type rError string

func (e rError) Error() string { return string(e) }
func (e rError) IsError()      {}

type rWarning string

func (w rWarning) Error() string { return string(w) }
func (w rWarning) IsWarning()    {}

func (r res) toError() error {
	if r.Error != "" {
		return rError(r.Error)
	} else if r.Warning != "" {
		if r.strict {
			return rError(r.Warning)
		}
		return rWarning(r.Warning)
	}
	return nil
}

// Strict sets all warnings to become errors. Setting this is
// recommended as R is generous as to what constitutes an error.
func (c *Conn) Strict() error {
	c.strict = true
	return c.R("options(warn=2)")
}

// R sends a command to R. An Error or Warning generated by the
// command will be returned as an RError or RWarning.
func (c *Conn) R(cmd string) error {
	if c.err != nil {
		return c.err
	}
	key := "r.result"
	rch := make(chan readerDone)
	c.server.putFwd(key, rch)
	defer c.server.rmFwd(key)
	fmt.Fprintf(c.inPipe, cmdStr, cmd, c.server.port, key)
	rd := <-rch
	defer close(rd.done)
	dec := json.NewDecoder(rd.r)
	var resultPair []string
	if err := dec.Decode(&resultPair); err != nil {
		c.err = fmt.Errorf("error while decoding result: %v", err)
		return c.err
	}
	if len(resultPair) != 2 {
		c.err = fmt.Errorf("invalid result pair: %v has length %d", resultPair, len(resultPair))
		return c.err
	}
	result := res{resultPair[0], resultPair[1], c.strict}
	c.err = result.toError()
	if IsWarning(c.err) {
		err := c.err
		c.err = nil
		return err
	}
	return c.err
}

// Rf is like R but takes a format string and arguments.
func (c *Conn) Rf(format string, args ...interface{}) error {
	return c.R(fmt.Sprintf(format, args...))
}

func (c *Conn) getuid() uint64 {
	x := c.counter
	c.counter++
	return x
}

func (c *Conn) write(data interface{}) (string, error) {
	b, err := json.Marshal(data)
	if err != nil {
		return "", err
	}
	key := fmt.Sprintf("go.data.%d", c.getuid())
	c.server.putData(key, b)
	return key, nil
}

// Send sends data into R. data must be json-serializable.
func (c *Conn) Send(data interface{}, name string) error {
	if c.err != nil {
		return c.err
	}
	key, err := c.write(data)
	if key != "" {
		defer c.server.rmData(key)
	}
	if err != nil {
		c.err = err
		return err
	}
	return c.Rf("%s = fromJSON(getURL(\"http://localhost:%d/%s\"))", name, c.server.port, key)
}

// SendDF sends a DataFrame and properly unpacks it as an
// R data frame.
func (c *Conn) SendDF(df *DataFrame, name string) error {
	colVars := make([]string, len(df.cols))
	for i, col := range df.cols {
		colVars[i] = "..rgo.df.cols." + strconv.Itoa(i)
		if err := c.Send(col, colVars[i]); err != nil {
			return err
		}
		// jsonlite may interpret integers as integers. This is not
		// desirable because R often treats integers more like enums
		// than integers. Force all numeric types to become doubles.
		if col.len() > 0 && isNumeric((*col.v)[0]) {
			err := c.Rf("%s <- as.double(%s)", colVars[i], colVars[i])
			if err != nil {
				return err
			}
		}
	}
	allColVars := strings.Join(colVars, ", ")
	if err := c.Send(df.colNames, "..rgo.df.colNames"); err != nil {
		return err
	}
	if !df.namelessRows {
		if err := c.Send(df.rowNames, "..rgo.df.rowNames"); err != nil {
			return err
		}
	}
	var err error
	if df.namelessRows {
		err = c.Rf("..rgo.df.result <- data.frame(%s)", allColVars)
	} else {
		err = c.Rf("..rgo.df.result <- data.frame(%s, row.names=..rgo.df.rowNames)", allColVars)
	}
	if err != nil {
		return err
	}
	if err := c.R("colnames(..rgo.df.result) <- ..rgo.df.colNames"); err != nil {
		return err
	}
	return c.Rf("%s <- ..rgo.df.result", name)
}

// Get gets data from R. data will be deserialized from json.
func (c *Conn) Get(data interface{}, name string) error {
	if c.err != nil {
		return c.err
	}
	key := fmt.Sprintf("r.data.%d", c.getuid())
	rch := make(chan readerDone)
	c.server.putFwd(key, rch)
	defer c.server.rmFwd(key)

	errCh := make(chan error)
	go func() {
		errCh <- c.Rf("httpPUT(\"http://localhost:%d/%s\", toJSON(%s))", c.server.port, key, name)
	}()

	rd := <-rch
	dec := json.NewDecoder(rd.r)
	err := dec.Decode(data)
	close(rd.done)
	c.err = <-errCh
	if c.err != nil {
		return c.err
	}
	c.err = err
	return err
}

// Error returns the first error that occured in the sequence of
// operations. R warnings are ignored.
func (c *Conn) Error() error {
	return c.err
}

type RError interface {
	error
	IsError()
}

type RWarning interface {
	error
	IsWarning()
}

func IsError(e error) bool {
	_, ok := e.(RError)
	return ok
}

func IsWarning(e error) bool {
	_, ok := e.(RWarning)
	return ok
}
<commit_msg>clarify how R memory is managed (it isn't)<commit_after>package rgo

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
)

// Conn is used to start and communicate with an R process. Conn
// is NOT thread-safe. However, you may run multiple Conn's in
// the same process safely. It is safe to run successive
// operations on Conn successively and retrieve any errors
// using Error(). Do not that although R warnings will be
// returned in method calls, they will not be captured in Error().
//
// Objects in R will not be freed until the Conn is closed.
type Conn struct {
	cmd     *exec.Cmd
	inPipe  io.WriteCloser
	counter uint64
	server  *server

	err    error
	strict bool
	closed bool
}

func (c *Conn) start() error {
	err := c.cmd.Start()
	if err != nil {
		return err
	}
	return err
}

type connConfig struct {
	debug bool
}

type ConnOption func(*connConfig)

func WithDebug() ConnOption {
	return func(c *connConfig) {
		c.debug = true
	}
}

const checkDepsCmd = "cat(is.element(\"jsonlite\", installed.packages()[,1]) & is.element(\"RCurl\", installed.packages()[,1]))\n"

func Connection(opts ...ConnOption) (*Conn, error) {
	var cfg connConfig
	for _, opt := range opts {
		opt(&cfg)
	}
	var c Conn
	out, err := exec.Command("R", "--no-save", "-s", "-e", checkDepsCmd).CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("failed to check dependencies: %v", err)
	}
	if string(out) != "TRUE" {
		fmt.Printf("got: %s", out)
		return nil, errors.New("need to install 'jsonlite' and 'RCurl'")
	}
	c.cmd = exec.Command("R", "--no-save")
	c.inPipe, err = c.cmd.StdinPipe()
	if cfg.debug {
		c.cmd.Stdout = os.Stdout
		c.cmd.Stderr = os.Stderr
	}
	if err != nil {
		return nil, err
	}
	err = c.start()
	if err != nil {
		return nil, err
	}
	if err != nil {
		c.Close()
		return nil, err
	}
	c.server, err = newServer()
	if err != nil {
		goto ErrCleanup
	}
	err = c.directR("library(jsonlite)\n")
	if err != nil {
		goto ErrCleanup
	}
	err = c.directR("library(RCurl)\n")
	if err != nil {
		goto ErrCleanup
	}
	runtime.SetFinalizer(&c, func(c *Conn) { c.Close() })
	return &c, nil

ErrCleanup:
	c.Close()
	return nil, err
}

func (c *Conn) Close() error {
	if c.closed {
		return nil
	}
	c.directR("q()")
	c.inPipe.Close()
	err1 := c.cmd.Wait()
	err2 := c.server.s.Stop()
	if err1 != nil {
		return err1
	}
	return err2
}

// directR sends the command to R without trapping errors.
// directR should only be used for registring some internal functions.
func (c *Conn) directR(cmd string) error {
	_, err := io.WriteString(c.inPipe, cmd)
	return err
}

const cmdStr = `..rgo.ret = c("", "")
tryCatch({
	%s
}, warning = function(w) {
	..rgo.ret[1] <<- conditionMessage(w)
}, error = function(e) {
	..rgo.ret[2] <<- conditionMessage(e)
})
print(..rgo.ret)
httpPUT("http://localhost:%d/%s", toJSON(..rgo.ret))
`

type res struct {
	Error   string
	Warning string
	strict  bool
}

type rError string

func (e rError) Error() string { return string(e) }
func (e rError) IsError()      {}

type rWarning string

func (w rWarning) Error() string { return string(w) }
func (w rWarning) IsWarning()    {}

func (r res) toError() error {
	if r.Error != "" {
		return rError(r.Error)
	} else if r.Warning != "" {
		if r.strict {
			return rError(r.Warning)
		}
		return rWarning(r.Warning)
	}
	return nil
}

// Strict sets all warnings to become errors. Setting this is
// recommended as R is generous as to what constitutes an error.
func (c *Conn) Strict() error {
	c.strict = true
	return c.R("options(warn=2)")
}

// R sends a command to R. An Error or Warning generated by the
// command will be returned as an RError or RWarning.
func (c *Conn) R(cmd string) error {
	if c.err != nil {
		return c.err
	}
	key := "r.result"
	rch := make(chan readerDone)
	c.server.putFwd(key, rch)
	defer c.server.rmFwd(key)
	fmt.Fprintf(c.inPipe, cmdStr, cmd, c.server.port, key)
	rd := <-rch
	defer close(rd.done)
	dec := json.NewDecoder(rd.r)
	var resultPair []string
	if err := dec.Decode(&resultPair); err != nil {
		c.err = fmt.Errorf("error while decoding result: %v", err)
		return c.err
	}
	if len(resultPair) != 2 {
		c.err = fmt.Errorf("invalid result pair: %v has length %d", resultPair, len(resultPair))
		return c.err
	}
	result := res{resultPair[0], resultPair[1], c.strict}
	c.err = result.toError()
	if IsWarning(c.err) {
		err := c.err
		c.err = nil
		return err
	}
	return c.err
}

// Rf is like R but takes a format string and arguments.
func (c *Conn) Rf(format string, args ...interface{}) error {
	return c.R(fmt.Sprintf(format, args...))
}

func (c *Conn) getuid() uint64 {
	x := c.counter
	c.counter++
	return x
}

func (c *Conn) write(data interface{}) (string, error) {
	b, err := json.Marshal(data)
	if err != nil {
		return "", err
	}
	key := fmt.Sprintf("go.data.%d", c.getuid())
	c.server.putData(key, b)
	return key, nil
}

// Send sends data into R. data must be json-serializable.
func (c *Conn) Send(data interface{}, name string) error {
	if c.err != nil {
		return c.err
	}
	key, err := c.write(data)
	if key != "" {
		defer c.server.rmData(key)
	}
	if err != nil {
		c.err = err
		return err
	}
	return c.Rf("%s = fromJSON(getURL(\"http://localhost:%d/%s\"))", name, c.server.port, key)
}

// SendDF sends a DataFrame and properly unpacks it as an
// R data frame.
func (c *Conn) SendDF(df *DataFrame, name string) error {
	colVars := make([]string, len(df.cols))
	for i, col := range df.cols {
		colVars[i] = "..rgo.df.cols." + strconv.Itoa(i)
		if err := c.Send(col, colVars[i]); err != nil {
			return err
		}
		// jsonlite may interpret integers as integers. This is not
		// desirable because R often treats integers more like enums
		// than integers. Force all numeric types to become doubles.
		if col.len() > 0 && isNumeric((*col.v)[0]) {
			err := c.Rf("%s <- as.double(%s)", colVars[i], colVars[i])
			if err != nil {
				return err
			}
		}
	}
	allColVars := strings.Join(colVars, ", ")
	if err := c.Send(df.colNames, "..rgo.df.colNames"); err != nil {
		return err
	}
	if !df.namelessRows {
		if err := c.Send(df.rowNames, "..rgo.df.rowNames"); err != nil {
			return err
		}
	}
	var err error
	if df.namelessRows {
		err = c.Rf("..rgo.df.result <- data.frame(%s)", allColVars)
	} else {
		err = c.Rf("..rgo.df.result <- data.frame(%s, row.names=..rgo.df.rowNames)", allColVars)
	}
	if err != nil {
		return err
	}
	if err := c.R("colnames(..rgo.df.result) <- ..rgo.df.colNames"); err != nil {
		return err
	}
	return c.Rf("%s <- ..rgo.df.result", name)
}

// Get gets data from R. data will be deserialized from json.
func (c *Conn) Get(data interface{}, name string) error {
	if c.err != nil {
		return c.err
	}
	key := fmt.Sprintf("r.data.%d", c.getuid())
	rch := make(chan readerDone)
	c.server.putFwd(key, rch)
	defer c.server.rmFwd(key)

	errCh := make(chan error)
	go func() {
		errCh <- c.Rf("httpPUT(\"http://localhost:%d/%s\", toJSON(%s))", c.server.port, key, name)
	}()

	rd := <-rch
	dec := json.NewDecoder(rd.r)
	err := dec.Decode(data)
	close(rd.done)
	c.err = <-errCh
	if c.err != nil {
		return c.err
	}
	c.err = err
	return err
}

// Error returns the first error that occured in the sequence of
// operations. R warnings are ignored.
func (c *Conn) Error() error {
	return c.err
}

type RError interface {
	error
	IsError()
}

type RWarning interface {
	error
	IsWarning()
}

func IsError(e error) bool {
	_, ok := e.(RError)
	return ok
}

func IsWarning(e error) bool {
	_, ok := e.(RWarning)
	return ok
}
<|endoftext|>


<commit_before>package rhynock

import (
	"github.com/gorilla/websocket"
	"net/http"
	"time"
	"log"
)

// Some defaults for pinging
// Needs to be settable from outside
const (
	writeWait = 10 * time.Second
	pongWait = 60 * time.Second
	pingPeriod = (pongWait * 9) / 10
	maxMessageSize = 512
)

// Conn encapsulates our websocket
type Conn struct {
	// Exported
	Ws      *websocket.Conn
	Send    chan []byte
	Dst     BottleDst
	Quit chan []byte
}

//
// Used to write a single message to the client and report any errors
//
func (c *Conn) write(t int, payload []byte) error {
	c.Ws.SetWriteDeadline(time.Now().Add(writeWait))
	return c.Ws.WriteMessage(t, payload)
}

//
// Maintains both a reader and a writer, cleans up both if one fails
//
func (c *Conn) read_write() {
	// Ping timer
	ticker := time.NewTicker(pingPeriod)

	// Clean up Connection and Connection resources
	defer func() {
		ticker.Stop()
		c.Ws.Close()
	}()

	// Config websocket settings
	c.Ws.SetReadLimit(maxMessageSize)
	c.Ws.SetReadDeadline(time.Now().Add(pongWait))
	c.Ws.SetPongHandler(func(string) error {
		// Give each client pongWait seconds after the ping to respond
		c.Ws.SetReadDeadline(time.Now().Add(pongWait))
		return nil
	})

	// Start a reading goroutine
	// The reader will stop when the c.Ws.Close is called at
	// in the defered cleanup function, so we do not manually
	// have to close the reader
	go func() {
		for {
			// This blcoks until it reads EOF or an error
			// occurs trying to read, the error can be
			// used to detect when the client closes the Connection
			_, message, err := c.Ws.ReadMessage()
			if err != nil {
				break // If we get an error escape the loop
			}

			// Bottle the message with its sender
			bottle := &Bottle{
				Sender: c,
				Message: message,
			}

			// Send to the destination for processing
			c.Dst.GetBottleChan() <- bottle
		}
		// The reader has been terminated

	}()

	// Main handling loop
	for {
		select {
		case message, ok := <- c.Send:
			// Our send channel has something in it or the channel closed
			if !ok {
				// Our channel was closed, gracefully close socket Conn
				c.write(websocket.CloseMessage, []byte{})
				return
			}
			// Attempt to write the message to the websocket
			if err := c.write(websocket.TextMessage, message); err != nil {
				// If we get an error we can no longer communcate with client
				// return, no need to send CloseMessage since that would
				// just yield another error
				return
			}

		case <- ticker.C:
			// Ping ticker went off. We need to ping to check for connectivity.
			if err := c.write(websocket.PingMessage, []byte{}); err != nil {
				// We got an error pinging, return and call defer
				// defer will close the socket which will kill the reader
				return
			}

		case bytes := <- c.Quit:
			// Close connection and send a final message
			c.write(websocket.TextMessage, bytes)
			c.write(websocket.CloseMessage, []byte{})
			return
		}
	}

}

//
// This function chews through the power cables
//
func (c *Conn) Close() {
	// Send ourself the quit signal with no message
	c.Quit <- []byte("")
}

var upgrader = &websocket.Upgrader{ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r* http.Request) bool { return true }}

//
// Hanlder function to start a websocket connection
//
func ConnectionHandler(w http.ResponseWriter, r *http.Request, dst BottleDst) {
	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
		return
	}

	// Create new connection object
	c := &Conn{
		Send: make(chan []byte, 256),
		Ws: ws,
		Dst: dst,
		Quit: make(chan []byte),
	}

	// Alert the destination that a new connection has opened
	dst.ConnectionOpened(c)

	// Start infinite read/write loop
	c.read_write()
}
<commit_msg>Happy easy functions<commit_after>package rhynock

import (
	"github.com/gorilla/websocket"
	"net/http"
	"time"
	"log"
)

// Some defaults for pinging
// Needs to be settable from outside
const (
	writeWait = 10 * time.Second
	pongWait = 60 * time.Second
	pingPeriod = (pongWait * 9) / 10
	maxMessageSize = 512
)

// Conn encapsulates our websocket
type Conn struct {
	// Exported so everything can be messed with from outside
	Ws      *websocket.Conn
	Send    chan []byte
	Dst     BottleDst
	Quit chan []byte
}

//
// Convenience function so you dont have to use the Send channel
//
func (c *Conn) Send(message string) {
	// Basically just typecasting for convenience
	c.Send <- []byte(message)
}

//
// Convenience function to call the quit channel with a message
//
func (c *Conn) Quit(message string) {
	c.Quit <- []byte(message)
}

//
// Used to write a single message to the client and report any errors
//
func (c *Conn) write(t int, payload []byte) error {
	c.Ws.SetWriteDeadline(time.Now().Add(writeWait))
	return c.Ws.WriteMessage(t, payload)
}

//
// Maintains both a reader and a writer, cleans up both if one fails
//
func (c *Conn) read_write() {
	// Ping timer
	ticker := time.NewTicker(pingPeriod)

	// Clean up Connection and Connection resources
	defer func() {
		ticker.Stop()
		c.Ws.Close()
	}()

	// Config websocket settings
	c.Ws.SetReadLimit(maxMessageSize)
	c.Ws.SetReadDeadline(time.Now().Add(pongWait))
	c.Ws.SetPongHandler(func(string) error {
		// Give each client pongWait seconds after the ping to respond
		c.Ws.SetReadDeadline(time.Now().Add(pongWait))
		return nil
	})

	// Start a reading goroutine
	// The reader will stop when the c.Ws.Close is called at
	// in the defered cleanup function, so we do not manually
	// have to close the reader
	go func() {
		for {
			// This blcoks until it reads EOF or an error
			// occurs trying to read, the error can be
			// used to detect when the client closes the Connection
			_, message, err := c.Ws.ReadMessage()
			if err != nil {
				break // If we get an error escape the loop
			}

			// Bottle the message with its sender
			bottle := &Bottle{
				Sender: c,
				Message: message,
			}

			// Send to the destination for processing
			c.Dst.GetBottleChan() <- bottle
		}
		// The reader has been terminated

	}()

	// Main handling loop
	for {
		select {
		case message, ok := <- c.Send:
			// Our send channel has something in it or the channel closed
			if !ok {
				// Our channel was closed, gracefully close socket Conn
				c.write(websocket.CloseMessage, []byte{})
				return
			}
			// Attempt to write the message to the websocket
			if err := c.write(websocket.TextMessage, message); err != nil {
				// If we get an error we can no longer communcate with client
				// return, no need to send CloseMessage since that would
				// just yield another error
				return
			}

		case <- ticker.C:
			// Ping ticker went off. We need to ping to check for connectivity.
			if err := c.write(websocket.PingMessage, []byte{}); err != nil {
				// We got an error pinging, return and call defer
				// defer will close the socket which will kill the reader
				return
			}

		case bytes := <- c.Quit:
			// Close connection and send a final message
			c.write(websocket.TextMessage, bytes)
			c.write(websocket.CloseMessage, []byte{})
			return
		}
	}

}

//
// This function chews through the power cables
//
func (c *Conn) Close() {
	// Send ourself the quit signal with no message
	c.Quit <- []byte("")
}

var upgrader = &websocket.Upgrader{ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r* http.Request) bool { return true }}

//
// Hanlder function to start a websocket connection
//
func ConnectionHandler(w http.ResponseWriter, r *http.Request, dst BottleDst) {
	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
		return
	}

	// Create new connection object
	c := &Conn{
		Send: make(chan []byte, 256),
		Ws: ws,
		Dst: dst,
		Quit: make(chan []byte),
	}

	// Alert the destination that a new connection has opened
	dst.ConnectionOpened(c)

	// Start infinite read/write loop
	c.read_write()
}
<|endoftext|>


<commit_before>package sftp

import (
	"encoding"
	"io"
	"sync"

	"github.com/pkg/errors"
)

// conn implements a bidirectional channel on which client and server
// connections are multiplexed.
type conn struct {
	io.Reader
	io.WriteCloser
	sync.Mutex // used to serialise writes to sendPacket
	// sendPacketTest is needed to replicate packet issues in testing
	sendPacketTest func(w io.Writer, m encoding.BinaryMarshaler) error
}

func (c *conn) recvPacket() (uint8, []byte, error) {
	return recvPacket(c)
}

func (c *conn) sendPacket(m encoding.BinaryMarshaler) error {
	c.Lock()
	defer c.Unlock()
	if c.sendPacketTest != nil {
		return c.sendPacketTest(c, m)
	}
	return sendPacket(c, m)
}

type clientConn struct {
	conn
	wg         sync.WaitGroup
	sync.Mutex                          // protects inflight
	inflight   map[uint32]chan<- result // outstanding requests
}

// Close closes the SFTP session.
func (c *clientConn) Close() error {
	defer c.wg.Wait()
	return c.conn.Close()
}

func (c *clientConn) loop() {
	defer c.wg.Done()
	err := c.recv()
	if err != nil {
		c.broadcastErr(err)
	}
}

// recv continuously reads from the server and forwards responses to the
// appropriate channel.
func (c *clientConn) recv() error {
	defer func() {
		c.conn.Lock()
		c.conn.Close()
		c.conn.Unlock()
	}()
	for {
		typ, data, err := c.recvPacket()
		if err != nil {
			return err
		}
		sid, _ := unmarshalUint32(data)
		c.Lock()
		ch, ok := c.inflight[sid]
		delete(c.inflight, sid)
		c.Unlock()
		if !ok {
			// This is an unexpected occurrence. Send the error
			// back to all listeners so that they terminate
			// gracefully.
			return errors.Errorf("sid: %v not fond", sid)
		}
		ch <- result{typ: typ, data: data}
	}
}

// result captures the result of receiving the a packet from the server
type result struct {
	typ  byte
	data []byte
	err  error
}

type idmarshaler interface {
	id() uint32
	encoding.BinaryMarshaler
}

func (c *clientConn) sendPacket(p idmarshaler) (byte, []byte, error) {
	ch := make(chan result, 1)
	c.dispatchRequest(ch, p)
	s := <-ch
	return s.typ, s.data, s.err
}

func (c *clientConn) dispatchRequest(ch chan<- result, p idmarshaler) {
	c.Lock()
	c.inflight[p.id()] = ch
	c.Unlock()
	if err := c.conn.sendPacket(p); err != nil {
		c.Lock()
		delete(c.inflight, p.id())
		c.Unlock()
		ch <- result{err: err}
	}
}

// broadcastErr sends an error to all goroutines waiting for a response.
func (c *clientConn) broadcastErr(err error) {
	c.Lock()
	listeners := make([]chan<- result, 0, len(c.inflight))
	for _, ch := range c.inflight {
		listeners = append(listeners, ch)
	}
	c.Unlock()
	for _, ch := range listeners {
		ch <- result{err: err}
	}
}

type serverConn struct {
	conn
}

func (s *serverConn) sendError(p ider, err error) error {
	return s.sendPacket(statusFromError(p, err))
}
<commit_msg>set inflight chan buffer to 2 for deadlock<commit_after>package sftp

import (
	"encoding"
	"io"
	"sync"

	"github.com/pkg/errors"
)

// conn implements a bidirectional channel on which client and server
// connections are multiplexed.
type conn struct {
	io.Reader
	io.WriteCloser
	sync.Mutex // used to serialise writes to sendPacket
	// sendPacketTest is needed to replicate packet issues in testing
	sendPacketTest func(w io.Writer, m encoding.BinaryMarshaler) error
}

func (c *conn) recvPacket() (uint8, []byte, error) {
	return recvPacket(c)
}

func (c *conn) sendPacket(m encoding.BinaryMarshaler) error {
	c.Lock()
	defer c.Unlock()
	if c.sendPacketTest != nil {
		return c.sendPacketTest(c, m)
	}
	return sendPacket(c, m)
}

type clientConn struct {
	conn
	wg         sync.WaitGroup
	sync.Mutex                          // protects inflight
	inflight   map[uint32]chan<- result // outstanding requests
}

// Close closes the SFTP session.
func (c *clientConn) Close() error {
	defer c.wg.Wait()
	return c.conn.Close()
}

func (c *clientConn) loop() {
	defer c.wg.Done()
	err := c.recv()
	if err != nil {
		c.broadcastErr(err)
	}
}

// recv continuously reads from the server and forwards responses to the
// appropriate channel.
func (c *clientConn) recv() error {
	defer func() {
		c.conn.Lock()
		c.conn.Close()
		c.conn.Unlock()
	}()
	for {
		typ, data, err := c.recvPacket()
		if err != nil {
			return err
		}
		sid, _ := unmarshalUint32(data)
		c.Lock()
		ch, ok := c.inflight[sid]
		delete(c.inflight, sid)
		c.Unlock()
		if !ok {
			// This is an unexpected occurrence. Send the error
			// back to all listeners so that they terminate
			// gracefully.
			return errors.Errorf("sid: %v not fond", sid)
		}
		ch <- result{typ: typ, data: data}
	}
}

// result captures the result of receiving the a packet from the server
type result struct {
	typ  byte
	data []byte
	err  error
}

type idmarshaler interface {
	id() uint32
	encoding.BinaryMarshaler
}

func (c *clientConn) sendPacket(p idmarshaler) (byte, []byte, error) {
	ch := make(chan result, 2)
	c.dispatchRequest(ch, p)
	s := <-ch
	return s.typ, s.data, s.err
}

func (c *clientConn) dispatchRequest(ch chan<- result, p idmarshaler) {
	c.Lock()
	c.inflight[p.id()] = ch
	c.Unlock()
	if err := c.conn.sendPacket(p); err != nil {
		c.Lock()
		delete(c.inflight, p.id())
		c.Unlock()
		ch <- result{err: err}
	}
}

// broadcastErr sends an error to all goroutines waiting for a response.
func (c *clientConn) broadcastErr(err error) {
	c.Lock()
	listeners := make([]chan<- result, 0, len(c.inflight))
	for _, ch := range c.inflight {
		listeners = append(listeners, ch)
	}
	c.Unlock()
	for _, ch := range listeners {
		ch <- result{err: err}
	}
}

type serverConn struct {
	conn
}

func (s *serverConn) sendError(p ider, err error) error {
	return s.sendPacket(statusFromError(p, err))
}
<|endoftext|>


<commit_before>// Copyright 2014 Mikio Hara. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipoam

import (
	"fmt"
	"net"
	"syscall"

	"golang.org/x/net/icmp"
	"golang.org/x/net/ipv4"
	"golang.org/x/net/ipv6"
)

const (
	// See golang.org/x/net/internal/iana.
	ianaProtocolIP       = 0
	ianaProtocolICMP     = 1
	ianaProtocolUDP      = 17
	ianaProtocolIPv6     = 41
	ianaProtocolIPv6ICMP = 58
)

// A conn represents a connection endpoint.
type conn struct {
	protocol  int            // protocol number
	rawSocket bool           // true if c is a raw socket
	ip        net.IP         // local address of c
	sport     int            // source port of c
	c         net.PacketConn // net.IPConn, net.UDPConn or icmp.PacketConn
	r4        *ipv4.RawConn
	p4        *ipv4.PacketConn
	p6        *ipv6.PacketConn
}

func (c *conn) close() error {
	if c == nil || c.c == nil {
		return syscall.EINVAL
	}
	return c.c.Close()
}

func (c *conn) readFrom(b []byte) ([]byte, interface{}, interface{}, net.Addr, error) {
	if !c.rawSocket {
		n, peer, err := c.c.ReadFrom(b)
		if err != nil {
			return nil, nil, nil, nil, err
		}
		return b[:n], nil, nil, peer, nil
	}
	switch c.protocol {
	case ianaProtocolICMP:
		if c.r4 != nil {
			h, p, cm, err := c.r4.ReadFrom(b)
			if err != nil {
				return nil, nil, nil, nil, err
			}
			return p, h, cm, &net.IPAddr{IP: cm.Src}, nil
		}
		n, cm, peer, err := c.p4.ReadFrom(b)
		return b[:n], nil, cm, peer, err
	case ianaProtocolIPv6ICMP:
		n, cm, peer, err := c.p6.ReadFrom(b)
		if err != nil {
			return nil, nil, nil, nil, err
		}
		return b[:n], nil, cm, peer, err
	default:
		return nil, nil, nil, nil, fmt.Errorf("unknown protocol: %d", c.protocol)
	}
}

func (c *conn) setup(maint bool) {
	switch la := c.c.LocalAddr().(type) {
	case *net.UDPAddr:
		c.ip = la.IP
		c.sport = la.Port
	case *net.IPAddr:
		c.rawSocket = true
		c.ip = la.IP
	}
	if c.rawSocket {
		switch c.protocol {
		case ianaProtocolICMP:
			if maint {
				c.r4, _ = ipv4.NewRawConn(c.c)
			} else {
				c.p4 = ipv4.NewPacketConn(c.c)
			}
		case ianaProtocolIPv6ICMP:
			c.p6 = ipv6.NewPacketConn(c.c)
		}
	} else {
		switch c.protocol {
		case ianaProtocolICMP, ianaProtocolIPv6ICMP:
			if c.ip.To4() != nil {
				c.p4 = c.c.(*icmp.PacketConn).IPv4PacketConn()
			}
			if c.ip.To16() != nil && c.ip.To4() == nil {
				c.p6 = c.c.(*icmp.PacketConn).IPv6PacketConn()
			}
		case ianaProtocolUDP:
			if c.ip.To4() != nil {
				c.p4 = ipv4.NewPacketConn(c.c)
			}
			if c.ip.To16() != nil && c.ip.To4() == nil {
				c.p6 = ipv6.NewPacketConn(c.c)
			}
		}
	}
}

func (c *conn) writeTo(b []byte, dst net.Addr, ifi *net.Interface) (int, error) {
	if !c.rawSocket {
		return c.c.WriteTo(b, dst)
	}
	switch c.protocol {
	case ianaProtocolICMP:
		var cm *ipv4.ControlMessage
		if ifi != nil {
			cm = &ipv4.ControlMessage{IfIndex: ifi.Index}
		}
		if c.r4 != nil {
			h := &ipv4.Header{
				Version:  ipv4.Version,
				Len:      ipv4.HeaderLen,
				TotalLen: ipv4.HeaderLen + len(b),
				Protocol: ianaProtocolICMP,
				Dst:      dst.(*net.IPAddr).IP,
			}
			if err := c.r4.WriteTo(h, b, cm); err != nil {
				return 0, err
			}
			return len(b), nil
		}
		return c.p4.WriteTo(b, cm, dst)
	case ianaProtocolIPv6ICMP:
		var cm *ipv6.ControlMessage
		if ifi != nil {
			cm = &ipv6.ControlMessage{IfIndex: ifi.Index}
		}
		return c.p6.WriteTo(b, cm, dst)
	default:
		return 0, fmt.Errorf("unknown protocol: %d", c.protocol)
	}
}

func newProbeConn(network, address string) (*conn, error) {
	var err error
	var c *conn
	switch network {
	case "ip4:icmp", "ip4:1", "ip6:ipv6-icmp", "ip6:58":
		c, err = newICMPConn(network, address)
	case "udp", "udp4", "udp6":
		c, err = newUDPConn(network, address)
	default:
		return nil, net.UnknownNetworkError(network)
	}
	if err != nil {
		return nil, err
	}
	c.setup(false)
	return c, nil
}

func newMaintConn(network, address string) (*conn, error) {
	var err error
	var c *conn
	switch network {
	case "ip4:icmp", "ip4:1", "ip6:ipv6-icmp", "ip6:58", "ip4:icmp+ip6:ipv6-icmp":
		c, err = newICMPConn(network, address)
	default:
		return nil, net.UnknownNetworkError(network)
	}
	if err != nil {
		return nil, err
	}
	c.setup(true)
	return c, nil
}

func newICMPConn(network, address string) (*conn, error) {
	ipa, err := net.ResolveIPAddr("ip", address)
	if err != nil {
		return nil, err
	}
	if ipa.IP == nil {
		switch network {
		case "ip4:icmp", "ip4:1", "ip4:icmp+ip6:ipv6-icmp":
			ipa.IP = net.IPv4zero
		case "ip6:ipv6-icmp", "ip6:58":
			ipa.IP = net.IPv6unspecified
		}
	}
	var conn conn
	var networks []string
	if ipa.IP.To4() != nil {
		networks = []string{"ip4:icmp", "udp4"}
		conn.protocol = ianaProtocolICMP
	}
	if ipa.IP.To16() != nil && ipa.IP.To4() == nil {
		networks = []string{"ip6:ipv6-icmp", "udp6"}
		conn.protocol = ianaProtocolIPv6ICMP
	}
	var firstErr error
	conn.c, firstErr = net.ListenPacket(networks[0], address)
	if firstErr != nil {
		conn.c, err = icmp.ListenPacket(networks[1], address)
		if err != nil {
			return nil, firstErr
		}
	}
	return &conn, nil
}

func newUDPConn(network, address string) (*conn, error) {
	c, err := net.ListenPacket(network, address)
	if err != nil {
		return nil, err
	}
	return &conn{protocol: ianaProtocolUDP, c: c}, nil
}
<commit_msg>ipoam: make ICMP for IPv6 transport correctly<commit_after>// Copyright 2014 Mikio Hara. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipoam

import (
	"fmt"
	"net"
	"syscall"

	"golang.org/x/net/icmp"
	"golang.org/x/net/ipv4"
	"golang.org/x/net/ipv6"
)

const (
	// See golang.org/x/net/internal/iana.
	ianaProtocolIP       = 0
	ianaProtocolICMP     = 1
	ianaProtocolUDP      = 17
	ianaProtocolIPv6     = 41
	ianaProtocolIPv6ICMP = 58
)

// A conn represents a connection endpoint.
type conn struct {
	protocol  int            // protocol number
	rawSocket bool           // true if c is a raw socket
	ip        net.IP         // local address of c
	sport     int            // source port of c
	c         net.PacketConn // net.IPConn, net.UDPConn or icmp.PacketConn
	r4        *ipv4.RawConn
	p4        *ipv4.PacketConn
	p6        *ipv6.PacketConn
}

func (c *conn) close() error {
	if c == nil || c.c == nil {
		return syscall.EINVAL
	}
	return c.c.Close()
}

func (c *conn) readFrom(b []byte) ([]byte, interface{}, interface{}, net.Addr, error) {
	if !c.rawSocket {
		n, peer, err := c.c.ReadFrom(b)
		if err != nil {
			return nil, nil, nil, nil, err
		}
		return b[:n], nil, nil, peer, nil
	}
	switch c.protocol {
	case ianaProtocolICMP:
		if c.r4 != nil {
			h, p, cm, err := c.r4.ReadFrom(b)
			if err != nil {
				return nil, nil, nil, nil, err
			}
			return p, h, cm, &net.IPAddr{IP: cm.Src}, nil
		}
		n, cm, peer, err := c.p4.ReadFrom(b)
		return b[:n], nil, cm, peer, err
	case ianaProtocolIPv6ICMP:
		n, cm, peer, err := c.p6.ReadFrom(b)
		if err != nil {
			return nil, nil, nil, nil, err
		}
		return b[:n], nil, cm, peer, err
	default:
		return nil, nil, nil, nil, fmt.Errorf("unknown protocol: %d", c.protocol)
	}
}

func (c *conn) setup(maint bool) {
	switch la := c.c.LocalAddr().(type) {
	case *net.UDPAddr:
		c.ip = la.IP
		c.sport = la.Port
	case *net.IPAddr:
		c.rawSocket = true
		c.ip = la.IP
	}
	if c.rawSocket {
		switch c.protocol {
		case ianaProtocolICMP:
			if maint {
				c.r4, _ = ipv4.NewRawConn(c.c)
			} else {
				c.p4 = ipv4.NewPacketConn(c.c)
			}
		case ianaProtocolIPv6ICMP:
			c.p6 = ipv6.NewPacketConn(c.c)
		}
	} else {
		switch c.protocol {
		case ianaProtocolICMP, ianaProtocolIPv6ICMP:
			if c.ip.To4() != nil {
				c.p4 = c.c.(*icmp.PacketConn).IPv4PacketConn()
			}
			if c.ip.To16() != nil && c.ip.To4() == nil {
				c.p6 = c.c.(*icmp.PacketConn).IPv6PacketConn()
			}
		case ianaProtocolUDP:
			if c.ip.To4() != nil {
				c.p4 = ipv4.NewPacketConn(c.c)
			}
			if c.ip.To16() != nil && c.ip.To4() == nil {
				c.p6 = ipv6.NewPacketConn(c.c)
			}
		}
	}
}

func (c *conn) writeTo(b []byte, dst net.Addr, ifi *net.Interface) (int, error) {
	if !c.rawSocket {
		return c.c.WriteTo(b, dst)
	}
	switch c.protocol {
	case ianaProtocolICMP:
		var cm *ipv4.ControlMessage
		if ifi != nil {
			cm = &ipv4.ControlMessage{IfIndex: ifi.Index}
		}
		if c.r4 != nil {
			h := &ipv4.Header{
				Version:  ipv4.Version,
				Len:      ipv4.HeaderLen,
				TotalLen: ipv4.HeaderLen + len(b),
				Protocol: ianaProtocolICMP,
				Dst:      dst.(*net.IPAddr).IP,
			}
			if err := c.r4.WriteTo(h, b, cm); err != nil {
				return 0, err
			}
			return len(b), nil
		}
		return c.p4.WriteTo(b, cm, dst)
	case ianaProtocolIPv6ICMP:
		var cm *ipv6.ControlMessage
		if ifi != nil {
			cm = &ipv6.ControlMessage{IfIndex: ifi.Index}
		}
		return c.p6.WriteTo(b, cm, dst)
	default:
		return 0, fmt.Errorf("unknown protocol: %d", c.protocol)
	}
}

func newProbeConn(network, address string) (*conn, error) {
	var err error
	var c *conn
	switch network {
	case "ip4:icmp", "ip4:1", "ip6:ipv6-icmp", "ip6:58":
		c, err = newICMPConn(network, address)
	case "udp", "udp4", "udp6":
		c, err = newUDPConn(network, address)
	default:
		return nil, net.UnknownNetworkError(network)
	}
	if err != nil {
		return nil, err
	}
	c.setup(false)
	return c, nil
}

func newMaintConn(network, address string) (*conn, error) {
	var err error
	var c *conn
	switch network {
	case "ip4:icmp", "ip4:1", "ip6:ipv6-icmp", "ip6:58", "ip4:icmp+ip6:ipv6-icmp":
		c, err = newICMPConn(network, address)
	default:
		return nil, net.UnknownNetworkError(network)
	}
	if err != nil {
		return nil, err
	}
	c.setup(true)
	return c, nil
}

func newICMPConn(network, address string) (*conn, error) {
	ip := net.ParseIP(address)
	if ip == nil || ip.IsUnspecified() {
		switch network {
		case "ip4:icmp", "ip4:1", "ip4:icmp+ip6:ipv6-icmp":
			ip = net.IPv4zero
		case "ip6:ipv6-icmp", "ip6:58":
			ip = net.IPv6unspecified
		}
	}
	var conn conn
	var networks []string
	if ip.To4() != nil {
		networks = []string{"ip4:icmp", "udp4"}
		conn.protocol = ianaProtocolICMP
	}
	if ip.To16() != nil && ip.To4() == nil {
		networks = []string{"ip6:ipv6-icmp", "udp6"}
		conn.protocol = ianaProtocolIPv6ICMP
	}
	var firstErr, err error
	conn.c, firstErr = net.ListenPacket(networks[0], address)
	if firstErr != nil {
		conn.c, err = icmp.ListenPacket(networks[1], address)
		if err != nil {
			return nil, firstErr
		}
	}
	return &conn, nil
}

func newUDPConn(network, address string) (*conn, error) {
	c, err := net.ListenPacket(network, address)
	if err != nil {
		return nil, err
	}
	return &conn{protocol: ianaProtocolUDP, c: c}, nil
}
<|endoftext|>


<commit_before>// Package instagram provides a minimialist instagram API wrapper.
package instagram

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

var (
	baseUrl = "https://api.instagram.com/v1"
)

type Api struct {
	ClientId    string
	AccessToken string
}

// Create an API with either a ClientId OR an accessToken. Only one is required. Access tokens are preferred because they keep rate limiting down.
func New(clientId string, accessToken string) *Api {
	if clientId == "" && accessToken == "" {
		panic("ClientId or AccessToken must be given to create an Api")
	}

	return &Api{
		ClientId:    clientId,
		AccessToken: accessToken,
	}
}

// -- Implementation of request --

func buildGetRequest(urlStr string, params url.Values) (*http.Request, error) {
	u, err := url.Parse(urlStr)
	if err != nil {
		return nil, err
	}

	// If we are getting, then we can't merge query params
	if params != nil {
		if u.RawQuery != "" {
			return nil, fmt.Errorf("Cannot merge query params in urlStr and params")
		}
		u.RawQuery = params.Encode()
	}

	return http.NewRequest("GET", u.String(), nil)
}

func (api *Api) extendParams(p url.Values) url.Values {
	if p == nil {
		p = url.Values{}
	}
	if api.AccessToken != "" {
		p.Set("access_token", api.AccessToken)
	} else {
		p.Set("client_id", api.ClientId)
	}
	return p
}

func (api *Api) get(path string, params url.Values, r interface{}) error {
	params = api.extendParams(params)
	req, err := buildGetRequest(urlify(path), params)
	if err != nil {
		return err
	}
	return api.do(req, r)
}

func (api *Api) do(req *http.Request, r interface{}) error {
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return apiError(resp)
	}

	return decodeResponse(resp.Body, r)
}

func decodeResponse(body io.Reader, to interface{}) error {
	// b, _ := ioutil.ReadAll(body)
	// fmt.Println("Body:",string(b))
	// err := json.Unmarshal(b, to)
	err := json.NewDecoder(body).Decode(to)

	if err != nil {
		return fmt.Errorf("instagram: error decoding body; %s", err.Error())
	}
	return nil
}

func apiError(resp *http.Response) error {
	m := new(MetaResponse)
	if err := decodeResponse(resp.Body, m); err != nil {
		return err
	}

	var err MetaError
	if m.Meta != nil {
		err = MetaError(*m.Meta)
	} else {
		err = MetaError(Meta{Code: resp.StatusCode, ErrorMessage: resp.Status})
	}
	return &err
}

func urlify(path string) string {
	return baseUrl + path
}

type MetaError Meta

func (m *MetaError) Error() string {
	return fmt.Sprintf("Error making api call: Code %d %s %s", m.Code, m.ErrorType, m.ErrorMessage)
}

func ensureParams(v url.Values) url.Values {
	if v == nil {
		return url.Values{}
	}
	return v
}
<commit_msg>chore(style): cleanup code a little<commit_after>// Package instagram provides a minimialist instagram API wrapper.
package instagram

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

var (
	baseUrl = "https://api.instagram.com/v1"
)

type Api struct {
	ClientId    string
	AccessToken string
}

// Create an API with either a ClientId OR an accessToken. Only one is required. Access tokens are preferred because they keep rate limiting down.
func New(clientId string, accessToken string) *Api {
	if clientId == "" && accessToken == "" {
		panic("ClientId or AccessToken must be given to create an Api")
	}

	return &Api{
		ClientId:    clientId,
		AccessToken: accessToken,
	}
}

// -- Implementation of request --

func buildGetRequest(urlStr string, params url.Values) (*http.Request, error) {
	u, err := url.Parse(urlStr)
	if err != nil {
		return nil, err
	}

	// If we are getting, then we can't merge query params
	if params != nil {
		if u.RawQuery != "" {
			return nil, fmt.Errorf("Cannot merge query params in urlStr and params")
		}
		u.RawQuery = params.Encode()
	}

	return http.NewRequest("GET", u.String(), nil)
}

func (api *Api) extendParams(p url.Values) url.Values {
	if p == nil {
		p = url.Values{}
	}
	if api.AccessToken != "" {
		p.Set("access_token", api.AccessToken)
	} else {
		p.Set("client_id", api.ClientId)
	}
	return p
}

func (api *Api) get(path string, params url.Values, r interface{}) error {
	params = api.extendParams(params)
	req, err := buildGetRequest(urlify(path), params)
	if err != nil {
		return err
	}
	return api.do(req, r)
}

func (api *Api) do(req *http.Request, r interface{}) error {
	resp, err := http.DefaultClient.Do(req)
	if resp.Body != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		return err
	}

	if resp.StatusCode != 200 {
		return apiError(resp)
	}

	return decodeResponse(resp.Body, r)
}

func decodeResponse(body io.Reader, to interface{}) error {
	err := json.NewDecoder(body).Decode(to)

	if err != nil {
		return fmt.Errorf("instagram: error decoding body; %s", err.Error())
	}
	return nil
}

func apiError(resp *http.Response) error {
	m := &MetaResponse{}
	if err := decodeResponse(resp.Body, m); err != nil {
		return err
	}

	var err MetaError
	if m.Meta != nil {
		err = MetaError(*m.Meta)
	} else {
		err = MetaError(Meta{Code: resp.StatusCode, ErrorMessage: resp.Status})
	}
	return &err
}

func urlify(path string) string {
	return baseUrl + path
}

type MetaError Meta

func (m *MetaError) Error() string {
	return fmt.Sprintf("Error making api call: Code %d %s %s", m.Code, m.ErrorType, m.ErrorMessage)
}

func ensureParams(v url.Values) url.Values {
	if v == nil {
		return url.Values{}
	}
	return v
}
<|endoftext|>


<commit_before>package handlers

import (
	"net/http"
	"strconv"
	"strings"
)

// CORSOption represents a functional option for configuring the CORS middleware.
type CORSOption func(*cors) error

type cors struct {
	h                      http.Handler
	allowedHeaders         []string
	allowedMethods         []string
	allowedOrigins         []string
	allowedOriginValidator OriginValidator
	exposedHeaders         []string
	maxAge                 int
	ignoreOptions          bool
	allowCredentials       bool
}

// OriginValidator takes an origin string and returns whether or not that origin is allowed.
type OriginValidator func(string) bool

var (
	defaultCorsMethods = []string{"GET", "HEAD", "POST"}
	defaultCorsHeaders = []string{"Accept", "Accept-Language", "Content-Language", "Origin"}
	// (WebKit/Safari v9 sends the Origin header by default in AJAX requests)
)

const (
	corsOptionMethod           string = "OPTIONS"
	corsAllowOriginHeader      string = "Access-Control-Allow-Origin"
	corsExposeHeadersHeader    string = "Access-Control-Expose-Headers"
	corsMaxAgeHeader           string = "Access-Control-Max-Age"
	corsAllowMethodsHeader     string = "Access-Control-Allow-Methods"
	corsAllowHeadersHeader     string = "Access-Control-Allow-Headers"
	corsAllowCredentialsHeader string = "Access-Control-Allow-Credentials"
	corsRequestMethodHeader    string = "Access-Control-Request-Method"
	corsRequestHeadersHeader   string = "Access-Control-Request-Headers"
	corsOriginHeader           string = "Origin"
	corsVaryHeader             string = "Vary"
	corsOriginMatchAll         string = "*"
)

func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	origin := r.Header.Get(corsOriginHeader)
	if !ch.isOriginAllowed(origin) {
		ch.h.ServeHTTP(w, r)
		return
	}

	if r.Method == corsOptionMethod {
		if ch.ignoreOptions {
			ch.h.ServeHTTP(w, r)
			return
		}

		if _, ok := r.Header[corsRequestMethodHeader]; !ok {
			w.WriteHeader(http.StatusBadRequest)
			return
		}

		method := r.Header.Get(corsRequestMethodHeader)
		if !ch.isMatch(method, ch.allowedMethods) {
			w.WriteHeader(http.StatusMethodNotAllowed)
			return
		}

		requestHeaders := strings.Split(r.Header.Get(corsRequestHeadersHeader), ",")
		allowedHeaders := []string{}
		for _, v := range requestHeaders {
			canonicalHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
			if canonicalHeader == "" || ch.isMatch(canonicalHeader, defaultCorsHeaders) {
				continue
			}

			if !ch.isMatch(canonicalHeader, ch.allowedHeaders) {
				w.WriteHeader(http.StatusForbidden)
				return
			}

			allowedHeaders = append(allowedHeaders, canonicalHeader)
		}

		if len(allowedHeaders) > 0 {
			w.Header().Set(corsAllowHeadersHeader, strings.Join(allowedHeaders, ","))
		}

		if ch.maxAge > 0 {
			w.Header().Set(corsMaxAgeHeader, strconv.Itoa(ch.maxAge))
		}

		if !ch.isMatch(method, defaultCorsMethods) {
			w.Header().Set(corsAllowMethodsHeader, method)
		}
	} else {
		if len(ch.exposedHeaders) > 0 {
			w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ","))
		}
	}

	if ch.allowCredentials {
		w.Header().Set(corsAllowCredentialsHeader, "true")
	}

	if len(ch.allowedOrigins) > 1 {
		w.Header().Set(corsVaryHeader, corsOriginHeader)
	}

	w.Header().Set(corsAllowOriginHeader, origin)

	ch.h.ServeHTTP(w, r)
}

// CORS provides Cross-Origin Resource Sharing middleware.
// Example:
//
//  import (
//      "net/http"
//
//      "github.com/gorilla/handlers"
//      "github.com/gorilla/mux"
//  )
//
//  func main() {
//      r := mux.NewRouter()
//      r.HandleFunc("/users", UserEndpoint)
//      r.HandleFunc("/projects", ProjectEndpoint)
//
//      // Apply the CORS middleware to our top-level router, with the defaults.
//      http.ListenAndServe(":8000", handlers.CORS()(r))
//  }
//
func CORS(opts ...CORSOption) func(http.Handler) http.Handler {
	return func(h http.Handler) http.Handler {
		ch := parseCORSOptions(opts...)
		ch.h = h
		return ch
	}
}

func parseCORSOptions(opts ...CORSOption) *cors {
	ch := &cors{
		allowedMethods: defaultCorsMethods,
		allowedHeaders: defaultCorsHeaders,
		allowedOrigins: []string{corsOriginMatchAll},
	}

	for _, option := range opts {
		option(ch)
	}

	return ch
}

//
// Functional options for configuring CORS.
//

// AllowedHeaders adds the provided headers to the list of allowed headers in a
// CORS request.
// This is an append operation so the headers Accept, Accept-Language,
// and Content-Language are always allowed.
// Content-Type must be explicitly declared if accepting Content-Types other than
// application/x-www-form-urlencoded, multipart/form-data, or text/plain.
func AllowedHeaders(headers []string) CORSOption {
	return func(ch *cors) error {
		for _, v := range headers {
			normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
			if normalizedHeader == "" {
				continue
			}

			if !ch.isMatch(normalizedHeader, ch.allowedHeaders) {
				ch.allowedHeaders = append(ch.allowedHeaders, normalizedHeader)
			}
		}

		return nil
	}
}

// AllowedMethods can be used to explicitly allow methods in the
// Access-Control-Allow-Methods header.
// This is a replacement operation so you must also
// pass GET, HEAD, and POST if you wish to support those methods.
func AllowedMethods(methods []string) CORSOption {
	return func(ch *cors) error {
		ch.allowedMethods = []string{}
		for _, v := range methods {
			normalizedMethod := strings.ToUpper(strings.TrimSpace(v))
			if normalizedMethod == "" {
				continue
			}

			if !ch.isMatch(normalizedMethod, ch.allowedMethods) {
				ch.allowedMethods = append(ch.allowedMethods, normalizedMethod)
			}
		}

		return nil
	}
}

// AllowedOrigins sets the allowed origins for CORS requests, as used in the
// 'Allow-Access-Control-Origin' HTTP header.
// Note: Passing in a []string{"*"} will allow any domain.
func AllowedOrigins(origins []string) CORSOption {
	return func(ch *cors) error {
		for _, v := range origins {
			if v == corsOriginMatchAll {
				ch.allowedOrigins = []string{corsOriginMatchAll}
				return nil
			}
		}

		ch.allowedOrigins = origins
		return nil
	}
}

// AllowedOriginValidator sets a function for evaluating allowed origins in CORS requests, represented by the
// 'Allow-Access-Control-Origin' HTTP header.
func AllowedOriginValidator(fn OriginValidator) CORSOption {
	return func(ch *cors) error {
		ch.allowedOriginValidator = fn
		return nil
	}
}

// ExposeHeaders can be used to specify headers that are available
// and will not be stripped out by the user-agent.
func ExposedHeaders(headers []string) CORSOption {
	return func(ch *cors) error {
		ch.exposedHeaders = []string{}
		for _, v := range headers {
			normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
			if normalizedHeader == "" {
				continue
			}

			if !ch.isMatch(normalizedHeader, ch.exposedHeaders) {
				ch.exposedHeaders = append(ch.exposedHeaders, normalizedHeader)
			}
		}

		return nil
	}
}

// MaxAge determines the maximum age (in seconds) between preflight requests. A
// maximum of 10 minutes is allowed. An age above this value will default to 10
// minutes.
func MaxAge(age int) CORSOption {
	return func(ch *cors) error {
		// Maximum of 10 minutes.
		if age > 600 {
			age = 600
		}

		ch.maxAge = age
		return nil
	}
}

// IgnoreOptions causes the CORS middleware to ignore OPTIONS requests, instead
// passing them through to the next handler. This is useful when your application
// or framework has a pre-existing mechanism for responding to OPTIONS requests.
func IgnoreOptions() CORSOption {
	return func(ch *cors) error {
		ch.ignoreOptions = true
		return nil
	}
}

// AllowCredentials can be used to specify that the user agent may pass
// authentication details along with the request.
func AllowCredentials() CORSOption {
	return func(ch *cors) error {
		ch.allowCredentials = true
		return nil
	}
}

func (ch *cors) isOriginAllowed(origin string) bool {
	if origin == "" {
		return false
	}

	if ch.allowedOriginValidator != nil {
		return ch.allowedOriginValidator(origin)
	}

	for _, allowedOrigin := range ch.allowedOrigins {
		if allowedOrigin == origin || allowedOrigin == corsOriginMatchAll {
			return true
		}
	}

	return false
}

func (ch *cors) isMatch(needle string, haystack []string) bool {
	for _, v := range haystack {
		if v == needle {
			return true
		}
	}

	return false
}
<commit_msg>Update cors.go<commit_after>package handlers

import (
	"net/http"
	"strconv"
	"strings"
)

// CORSOption represents a functional option for configuring the CORS middleware.
type CORSOption func(*cors) error

type cors struct {
	h                      http.Handler
	allowedHeaders         []string
	allowedMethods         []string
	allowedOrigins         []string
	allowedOriginValidator OriginValidator
	exposedHeaders         []string
	maxAge                 int
	ignoreOptions          bool
	allowCredentials       bool
}

// OriginValidator takes an origin string and returns whether or not that origin is allowed.
type OriginValidator func(string) bool

var (
	defaultCorsMethods = []string{"GET", "HEAD", "POST"}
	defaultCorsHeaders = []string{"Accept", "Accept-Language", "Content-Language", "Origin"}
	// (WebKit/Safari v9 sends the Origin header by default in AJAX requests)
)

const (
	corsOptionMethod           string = "OPTIONS"
	corsAllowOriginHeader      string = "Access-Control-Allow-Origin"
	corsExposeHeadersHeader    string = "Access-Control-Expose-Headers"
	corsMaxAgeHeader           string = "Access-Control-Max-Age"
	corsAllowMethodsHeader     string = "Access-Control-Allow-Methods"
	corsAllowHeadersHeader     string = "Access-Control-Allow-Headers"
	corsAllowCredentialsHeader string = "Access-Control-Allow-Credentials"
	corsRequestMethodHeader    string = "Access-Control-Request-Method"
	corsRequestHeadersHeader   string = "Access-Control-Request-Headers"
	corsOriginHeader           string = "Origin"
	corsVaryHeader             string = "Vary"
	corsOriginMatchAll         string = "*"
)

func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	origin := r.Header.Get(corsOriginHeader)
	if !ch.isOriginAllowed(origin) {
		ch.h.ServeHTTP(w, r)
		return
	}

	if r.Method == corsOptionMethod {
		if ch.ignoreOptions {
			ch.h.ServeHTTP(w, r)
			return
		}

		if _, ok := r.Header[corsRequestMethodHeader]; !ok {
			w.WriteHeader(http.StatusBadRequest)
			return
		}

		method := r.Header.Get(corsRequestMethodHeader)
		if !ch.isMatch(method, ch.allowedMethods) {
			w.WriteHeader(http.StatusMethodNotAllowed)
			return
		}

		requestHeaders := strings.Split(r.Header.Get(corsRequestHeadersHeader), ",")
		allowedHeaders := []string{}
		for _, v := range requestHeaders {
			canonicalHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
			if canonicalHeader == "" || ch.isMatch(canonicalHeader, defaultCorsHeaders) {
				continue
			}

			if !ch.isMatch(canonicalHeader, ch.allowedHeaders) {
				w.WriteHeader(http.StatusForbidden)
				return
			}

			allowedHeaders = append(allowedHeaders, canonicalHeader)
		}

		if len(allowedHeaders) > 0 {
			w.Header().Set(corsAllowHeadersHeader, strings.Join(allowedHeaders, ","))
		}

		if ch.maxAge > 0 {
			w.Header().Set(corsMaxAgeHeader, strconv.Itoa(ch.maxAge))
		}

		if !ch.isMatch(method, defaultCorsMethods) {
			w.Header().Set(corsAllowMethodsHeader, method)
		}
	} else {
		if len(ch.exposedHeaders) > 0 {
			w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, ","))
		}
	}

	if ch.allowCredentials {
		w.Header().Set(corsAllowCredentialsHeader, "true")
	}

	if len(ch.allowedOrigins) > 1 {
		w.Header().Set(corsVaryHeader, corsOriginHeader)
	}

	w.Header().Set(corsAllowOriginHeader, origin)

	if r.Method == corsOptionMethod {
		return
	}
	ch.h.ServeHTTP(w, r)
}

// CORS provides Cross-Origin Resource Sharing middleware.
// Example:
//
//  import (
//      "net/http"
//
//      "github.com/gorilla/handlers"
//      "github.com/gorilla/mux"
//  )
//
//  func main() {
//      r := mux.NewRouter()
//      r.HandleFunc("/users", UserEndpoint)
//      r.HandleFunc("/projects", ProjectEndpoint)
//
//      // Apply the CORS middleware to our top-level router, with the defaults.
//      http.ListenAndServe(":8000", handlers.CORS()(r))
//  }
//
func CORS(opts ...CORSOption) func(http.Handler) http.Handler {
	return func(h http.Handler) http.Handler {
		ch := parseCORSOptions(opts...)
		ch.h = h
		return ch
	}
}

func parseCORSOptions(opts ...CORSOption) *cors {
	ch := &cors{
		allowedMethods: defaultCorsMethods,
		allowedHeaders: defaultCorsHeaders,
		allowedOrigins: []string{corsOriginMatchAll},
	}

	for _, option := range opts {
		option(ch)
	}

	return ch
}

//
// Functional options for configuring CORS.
//

// AllowedHeaders adds the provided headers to the list of allowed headers in a
// CORS request.
// This is an append operation so the headers Accept, Accept-Language,
// and Content-Language are always allowed.
// Content-Type must be explicitly declared if accepting Content-Types other than
// application/x-www-form-urlencoded, multipart/form-data, or text/plain.
func AllowedHeaders(headers []string) CORSOption {
	return func(ch *cors) error {
		for _, v := range headers {
			normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
			if normalizedHeader == "" {
				continue
			}

			if !ch.isMatch(normalizedHeader, ch.allowedHeaders) {
				ch.allowedHeaders = append(ch.allowedHeaders, normalizedHeader)
			}
		}

		return nil
	}
}

// AllowedMethods can be used to explicitly allow methods in the
// Access-Control-Allow-Methods header.
// This is a replacement operation so you must also
// pass GET, HEAD, and POST if you wish to support those methods.
func AllowedMethods(methods []string) CORSOption {
	return func(ch *cors) error {
		ch.allowedMethods = []string{}
		for _, v := range methods {
			normalizedMethod := strings.ToUpper(strings.TrimSpace(v))
			if normalizedMethod == "" {
				continue
			}

			if !ch.isMatch(normalizedMethod, ch.allowedMethods) {
				ch.allowedMethods = append(ch.allowedMethods, normalizedMethod)
			}
		}

		return nil
	}
}

// AllowedOrigins sets the allowed origins for CORS requests, as used in the
// 'Allow-Access-Control-Origin' HTTP header.
// Note: Passing in a []string{"*"} will allow any domain.
func AllowedOrigins(origins []string) CORSOption {
	return func(ch *cors) error {
		for _, v := range origins {
			if v == corsOriginMatchAll {
				ch.allowedOrigins = []string{corsOriginMatchAll}
				return nil
			}
		}

		ch.allowedOrigins = origins
		return nil
	}
}

// AllowedOriginValidator sets a function for evaluating allowed origins in CORS requests, represented by the
// 'Allow-Access-Control-Origin' HTTP header.
func AllowedOriginValidator(fn OriginValidator) CORSOption {
	return func(ch *cors) error {
		ch.allowedOriginValidator = fn
		return nil
	}
}

// ExposeHeaders can be used to specify headers that are available
// and will not be stripped out by the user-agent.
func ExposedHeaders(headers []string) CORSOption {
	return func(ch *cors) error {
		ch.exposedHeaders = []string{}
		for _, v := range headers {
			normalizedHeader := http.CanonicalHeaderKey(strings.TrimSpace(v))
			if normalizedHeader == "" {
				continue
			}

			if !ch.isMatch(normalizedHeader, ch.exposedHeaders) {
				ch.exposedHeaders = append(ch.exposedHeaders, normalizedHeader)
			}
		}

		return nil
	}
}

// MaxAge determines the maximum age (in seconds) between preflight requests. A
// maximum of 10 minutes is allowed. An age above this value will default to 10
// minutes.
func MaxAge(age int) CORSOption {
	return func(ch *cors) error {
		// Maximum of 10 minutes.
		if age > 600 {
			age = 600
		}

		ch.maxAge = age
		return nil
	}
}

// IgnoreOptions causes the CORS middleware to ignore OPTIONS requests, instead
// passing them through to the next handler. This is useful when your application
// or framework has a pre-existing mechanism for responding to OPTIONS requests.
func IgnoreOptions() CORSOption {
	return func(ch *cors) error {
		ch.ignoreOptions = true
		return nil
	}
}

// AllowCredentials can be used to specify that the user agent may pass
// authentication details along with the request.
func AllowCredentials() CORSOption {
	return func(ch *cors) error {
		ch.allowCredentials = true
		return nil
	}
}

func (ch *cors) isOriginAllowed(origin string) bool {
	if origin == "" {
		return false
	}

	if ch.allowedOriginValidator != nil {
		return ch.allowedOriginValidator(origin)
	}

	for _, allowedOrigin := range ch.allowedOrigins {
		if allowedOrigin == origin || allowedOrigin == corsOriginMatchAll {
			return true
		}
	}

	return false
}

func (ch *cors) isMatch(needle string, haystack []string) bool {
	for _, v := range haystack {
		if v == needle {
			return true
		}
	}

	return false
}
<|endoftext|>


<commit_before>package coup

type Coup struct {
	Subject *Player
	Object  *Player
}

func NewCoup(sub *Player, obj *Player) *Coup {
	return &Coup{
		Subject: sub,
		Object:  obj,
	}
}

func (c *Coup) Pay() {
	c.Subject.Coins -= 7
}

func (c *Coup) Claim() *Claim {
	return nil
}

func (c *Coup) Counter() *func(game *Game) *Block {
	return nil
}

func (c *Coup) Resolve() func(game *Game) {
	return func(game *Game) {

	}
}
<commit_msg>Coup Removes a Life<commit_after>package coup

type Coup struct {
	Subject *Player
	Object  *Player
}

func NewCoup(sub *Player, obj *Player) *Coup {
	return &Coup{
		Subject: sub,
		Object:  obj,
	}
}

func (c *Coup) Pay() {
	c.Subject.Coins -= 7
}

func (c *Coup) Claim() *Claim {
	return nil
}

func (c *Coup) Counter() *func(game *Game) *Block {
	return nil
}

func (c *Coup) Resolve() func(game *Game) {
	return func(game *Game) {
		game.Board.Deck.Add(c.Object.Discard(c.Object.Chooser.ChooseDiscard()))
	}
}
<|endoftext|>


<commit_before>package echo

import "fmt"

type Data struct {
	Code int
	Info interface{}
	Zone interface{} `json:",omitempty" xml:",omitempty"`
	Data interface{} `json:",omitempty" xml:",omitempty"`
}

func (d *Data) Error() string {
	return fmt.Sprintf(`%v`, d.Info)
}

func (d *Data) SetError(err error) *Data {
	if err != nil {
		d.Code = 0
		d.Info = err.Error()
	} else {
		d.Code = 1
	}
	return d
}

func (d *Data) SetCode(code int) *Data {
	d.Code = code
	return d
}

func (d *Data) SetInfo(info interface{}, args ...int) *Data {
	d.Info = info
	if len(args) > 0 {
		d.Code = args[0]
	}
	return d
}

func (d *Data) SetZone(zone interface{}) *Data {
	d.Zone = zone
	return d
}

func (d *Data) SetData(data interface{}, args ...int) *Data {
	d.Data = data
	if len(args) > 0 {
		d.Code = args[0]
	}
	return d
}

// NewData params: CIZD
func NewData(code int, args ...interface{}) *Data {
	var info, zone, data interface{}
	switch len(args) {
	case 3:
		data = args[2]
		fallthrough
	case 2:
		zone = args[1]
		fallthrough
	case 1:
		info = args[0]
	}
	return &Data{
		Code: code,
		Info: info,
		Zone: zone,
		Data: data,
	}
}
<commit_msg>update<commit_after>package echo

import "fmt"

type Data struct {
	Code int
	Info interface{}
	Zone interface{} `json:",omitempty" xml:",omitempty"`
	Data interface{} `json:",omitempty" xml:",omitempty"`
}

func (d *Data) Error() string {
	return fmt.Sprintf(`%v`, d.Info)
}

func (d *Data) SetError(err error, args ...int) *Data {
	if err != nil {
		if len(args) > 0 {
			d.Code = args[0]
		} else {
			d.Code = 0
		}
		d.Info = err.Error()
	} else {
		d.Code = 1
	}
	return d
}

func (d *Data) SetCode(code int) *Data {
	d.Code = code
	return d
}

func (d *Data) SetInfo(info interface{}, args ...int) *Data {
	d.Info = info
	if len(args) > 0 {
		d.Code = args[0]
	}
	return d
}

func (d *Data) SetZone(zone interface{}) *Data {
	d.Zone = zone
	return d
}

func (d *Data) SetData(data interface{}, args ...int) *Data {
	d.Data = data
	if len(args) > 0 {
		d.Code = args[0]
	} else {
		d.Code = 1
	}
	return d
}

// NewData params: CIZD
func NewData(code int, args ...interface{}) *Data {
	var info, zone, data interface{}
	switch len(args) {
	case 3:
		data = args[2]
		fallthrough
	case 2:
		zone = args[1]
		fallthrough
	case 1:
		info = args[0]
	}
	return &Data{
		Code: code,
		Info: info,
		Zone: zone,
		Data: data,
	}
}
<|endoftext|>