<commit_before>package dnssd

import (
	"context"
	"github.com/miekg/dns"
	"net"
	"testing"
	"time"
)

var testIface = &net.Interface{
	Index:        0,
	MTU:          0,
	Name:         "lo0",
	HardwareAddr: []byte{},
	Flags:        net.FlagUp,
}

var testAddr = net.UDPAddr{
	IP:   net.IP{},
	Port: 1234,
	Zone: "",
}

type testConn struct {
	read chan *Request

	in  chan *dns.Msg
	out chan *dns.Msg
}

func newTestConn() *testConn {
	c := &testConn{
		read: make(chan *Request),
		in:   make(chan *dns.Msg),
		out:  make(chan *dns.Msg),
	}

	return c
}

func (c *testConn) SendQuery(q *Query) error {
	go func() {
		c.out <- q.msg
	}()
	return nil
}

func (c *testConn) SendResponse(resp *Response) error {
	go func() {
		c.out <- resp.msg
	}()

	return nil
}

func (c *testConn) Read(ctx context.Context) <-chan *Request {
	go c.start(ctx)
	return c.read
}

func (c *testConn) Drain(ctx context.Context) {}

func (c *testConn) Close() {}

func (c *testConn) start(ctx context.Context) {
	for {
		select {
		case msg := <-c.in:
			req := &Request{msg: msg, from: &testAddr, iface: testIface}
			c.read <- req
		case <-ctx.Done():
			return
		default:
			break
		}
	}
}

// TestProbing tests probing by using 2 services with the same
// service instance name and host name.Once the first services
// is announced, the probing for the second service should give
func TestProbing(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	conn := newTestConn()
	otherConn := newTestConn()
	conn.in = otherConn.out
	conn.out = otherConn.in

	cfg := Config{
		Name: "My Service",
		Type: "_hap._tcp",
		Host: "My-Computer",
		Port: 12334,
		ifaceIPs: map[string][]net.IP{
			testIface.Name: []net.IP{net.ParseIP("192.168.0.122")},
		},
	}
	srv, err := NewService(cfg)
	if err != nil {
		t.Fatal(err)
	}

	go func() {
		otherCfg := cfg.Copy()
		otherCfg.IPs = []net.IP{net.ParseIP("192.168.0.123")}
		otherCfg.ifaceIPs = map[string][]net.IP{}
		otherSrv, otherErr := NewService(otherCfg)
		if otherErr != nil {
			t.Fatal(otherErr)
		}
		otherResp := newResponder(otherConn)
		otherResp.Add(otherSrv)

		otherCtx, otherCancel := context.WithCancel(ctx)
		defer otherCancel()

		// the responder won't probe for the service instance name and host name
		// because we explicitely set the IP address.
		otherResp.Respond(otherCtx)
	}()

	// Wait until second service was announced.
	// This doesn't take long because we set the IP address
	// explicitely. Therefore no probing is done.
	<-time.After(100 * time.Millisecond)

	resolved, err := probeService(ctx, conn, srv, 1*time.Second, true)

	if x := err; x != nil {
		t.Fatal(x)
	}

	if is, want := resolved.Host, "My-Computer-2"; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}

	if is, want := resolved.Name, "My Service-2"; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}
}

func TestIsLexicographicLater(t *testing.T) {
	this := &dns.A{
		Hdr: dns.RR_Header{
			Name:   "MyPrinter.local.",
			Rrtype: dns.TypeA,
			Class:  dns.ClassINET,
			Ttl:    TtlHostname,
		},
		A: net.ParseIP("169.254.99.200"),
	}

	that := &dns.A{
		Hdr: dns.RR_Header{
			Name:   "MyPrinter.local.",
			Rrtype: dns.TypeA,
			Class:  dns.ClassINET,
			Ttl:    TtlHostname,
		},
		A: net.ParseIP("169.254.200.50"),
	}

	if is, want := compareIP(this.A.To4(), that.A.To4()), -1; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}

	if is, want := compareIP(that.A.To4(), this.A.To4()), 1; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}
}
<commit_msg>Another try to fix the probing test<commit_after>package dnssd

import (
	"context"
	"github.com/miekg/dns"
	"net"
	"testing"
	"time"
)

var testIface = &net.Interface{
	Index:        0,
	MTU:          0,
	Name:         "lo0",
	HardwareAddr: []byte{},
	Flags:        net.FlagUp,
}

var testAddr = net.UDPAddr{
	IP:   net.IP{},
	Port: 1234,
	Zone: "",
}

type testConn struct {
	read chan *Request

	in  chan *dns.Msg
	out chan *dns.Msg
}

func newTestConn() *testConn {
	c := &testConn{
		read: make(chan *Request),
		in:   make(chan *dns.Msg),
		out:  make(chan *dns.Msg),
	}

	return c
}

func (c *testConn) SendQuery(q *Query) error {
	go func() {
		c.out <- q.msg
	}()
	return nil
}

func (c *testConn) SendResponse(resp *Response) error {
	go func() {
		c.out <- resp.msg
	}()

	return nil
}

func (c *testConn) Read(ctx context.Context) <-chan *Request {
	go c.start(ctx)
	return c.read
}

func (c *testConn) Drain(ctx context.Context) {}

func (c *testConn) Close() {}

func (c *testConn) start(ctx context.Context) {
	for {
		select {
		case msg := <-c.in:
			req := &Request{msg: msg, from: &testAddr, iface: testIface}
			c.read <- req
		case <-ctx.Done():
			return
		default:
			break
		}
	}
}

// TestProbing tests probing by using 2 services with the same
// service instance name and host name.Once the first services
// is announced, the probing for the second service should give
func TestProbing(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	conn := newTestConn()
	otherConn := newTestConn()
	conn.in = otherConn.out
	conn.out = otherConn.in

	cfg := Config{
		Name: "My Service",
		Type: "_hap._tcp",
		Host: "My-Computer",
		Port: 12334,
		ifaceIPs: map[string][]net.IP{
			testIface.Name: []net.IP{net.ParseIP("192.168.0.122")},
		},
	}
	srv, err := NewService(cfg)
	if err != nil {
		t.Fatal(err)
	}

	go func() {
		otherCfg := cfg.Copy()
		otherCfg.IPs = []net.IP{net.ParseIP("192.168.0.123")}
		otherCfg.ifaceIPs = nil
		otherSrv, otherErr := NewService(otherCfg)
		if otherErr != nil {
			t.Fatal(otherErr)
		}
		otherResp := newResponder(otherConn)
		otherResp.Add(otherSrv)

		otherCtx, otherCancel := context.WithCancel(ctx)
		defer otherCancel()

		// the responder won't probe for the service instance name and host name
		// because we explicitely set the IP address.
		otherResp.Respond(otherCtx)
	}()

	// Wait until second service was announced.
	// This doesn't take long because we set the IP address
	// explicitely. Therefore no probing is done.
	<-time.After(100 * time.Millisecond)

	resolved, err := probeService(ctx, conn, srv, 1*time.Second, true)

	if x := err; x != nil {
		t.Fatal(x)
	}

	if is, want := resolved.Host, "My-Computer-2"; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}

	if is, want := resolved.Name, "My Service-2"; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}
}

func TestIsLexicographicLater(t *testing.T) {
	this := &dns.A{
		Hdr: dns.RR_Header{
			Name:   "MyPrinter.local.",
			Rrtype: dns.TypeA,
			Class:  dns.ClassINET,
			Ttl:    TtlHostname,
		},
		A: net.ParseIP("169.254.99.200"),
	}

	that := &dns.A{
		Hdr: dns.RR_Header{
			Name:   "MyPrinter.local.",
			Rrtype: dns.TypeA,
			Class:  dns.ClassINET,
			Ttl:    TtlHostname,
		},
		A: net.ParseIP("169.254.200.50"),
	}

	if is, want := compareIP(this.A.To4(), that.A.To4()), -1; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}

	if is, want := compareIP(that.A.To4(), this.A.To4()), 1; is != want {
		t.Fatalf("is=%v want=%v", is, want)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"os"
	"os/exec"
	"strings"
	"unicode"
)

// generates snake case json tags so that you won't need to write them. Can be also exteded to xml or sql tags
func main() {
	fset := token.NewFileSet() // positions are relative to fset
	args := os.Args[1:]
	if len(args) < 2 {
		fmt.Println("Usage : easytags {file_name} {tag_name} {debug (true/false)} \n example: easytags file.go json true")
		return
	}
	debug := false
	if len(args) == 3 {
		if args[2] == "true" {
			debug = true
		}
	}
	tagName := args[1]
	// Parse the file containing this very example
	f, err := parser.ParseFile(fset, args[0], nil, parser.ParseComments)
	if err != nil {
		fmt.Println("Error")
		fmt.Println(err)
		return
	}

	lines, err := readLines(args[0])
	if err != nil {
		fmt.Printf("Error reading file %v \n ", err)
		return
	}

	for _, d := range f.Scope.Objects {
		if d.Kind == ast.Typ {
			ts, ok := d.Decl.(*ast.TypeSpec)
			if !ok {
				fmt.Printf("Unknown type without TypeSec: %v", d)
				return
			}

			x, ok := ts.Type.(*ast.StructType)
			if !ok {
				continue
			}
			for _, field := range x.Fields.List {
				line := fset.File(field.Pos()).Line(field.Pos())
				line = line - 1
				if field.Tag == nil {
					name := field.Names[0].String()
					if debug {
						fmt.Printf("Replacing line %s \n ", lines[line])
					}
					lines[line] = fmt.Sprintf("%s %v `%s:\"%s\"`", name, field.Type, tagName, ToSnake(name))
					if debug {
						fmt.Printf("By line : %s \n", lines[line])
					}
				} else if !strings.Contains(field.Tag.Value, fmt.Sprintf("%s:", tagName)) {
					name := field.Names[0].String()
					if debug {
						fmt.Printf("Replacing line %s \n ", lines[line])
					}
					lines[line] = fmt.Sprintf("%s %v `%s:\"%s\" %s`", name, field.Type, tagName, ToSnake(name), strings.Replace(field.Tag.Value, "`", "", 2))
					if debug {
						fmt.Printf("By line : %s \n", lines[line])
					}

				}

			}
		}
	}
	writeLines(lines, args[0])
	cmd := exec.Command("go", "fmt", args[0])
	cmd.Run()
}

// readLines reads a whole file into memory
// and returns a slice of its lines.
// original source : http://stackoverflow.com/questions/5884154/golang-read-text-file-into-string-array-and-write
func readLines(path string) ([]string, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var lines []string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines, scanner.Err()
}

// writeLines writes the lines to the given file.
func writeLines(lines []string, path string) error {
	file, err := os.Create(path)
	if err != nil {
		return err
	}
	defer file.Close()

	w := bufio.NewWriter(file)
	for _, line := range lines {
		fmt.Fprintln(w, line)
	}
	return w.Flush()
}

// ToSnake convert the given string to snake case following the Golang format:
// acronyms are converted to lower-case and preceded by an underscore.
// Original source : https://gist.github.com/elwinar/14e1e897fdbe4d3432e1
func ToSnake(in string) string {
	runes := []rune(in)
	length := len(runes)

	var out []rune
	for i := 0; i < length; i++ {
		if i > 0 && unicode.IsUpper(runes[i]) && ((i+1 < length && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1])) {
			out = append(out, '_')
		}
		out = append(out, unicode.ToLower(runes[i]))
	}

	return string(out)
}
<commit_msg>Added line comments for large main function<commit_after>package main

import (
	"bufio"
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"os"
	"os/exec"
	"strings"
	"unicode"
)

// generates snake case json tags so that you won't need to write them. Can be also exteded to xml or sql tags
func main() {
	fset := token.NewFileSet() // positions are relative to fset
	args := os.Args[1:]
	if len(args) < 2 {
		fmt.Println("Usage : easytags {file_name} {tag_name} {debug (true/false)} \n example: easytags file.go json true")
		return
	}
	debug := false
	if len(args) == 3 {
		if args[2] == "true" {
			debug = true
		}
	}
	tagName := args[1]
	// Parse the file given in arguments
	f, err := parser.ParseFile(fset, args[0], nil, parser.ParseComments)
	if err != nil {
		fmt.Println("Error")
		fmt.Println(err)
		return
	}
	// read entire source file as a slice of lines
	lines, err := readLines(args[0])
	if err != nil {
		fmt.Printf("Error reading file %v \n ", err)
		return
	}
	// range over the objects in the scope of this generated AST and check for StructType. Then range over fields
	// contained in that struct.
	for _, d := range f.Scope.Objects {
		if d.Kind == ast.Typ {
			ts, ok := d.Decl.(*ast.TypeSpec)
			if !ok {
				fmt.Printf("Unknown type without TypeSec: %v", d)
				return
			}

			x, ok := ts.Type.(*ast.StructType)
			if !ok {
				continue
			}
			for _, field := range x.Fields.List {
				line := fset.File(field.Pos()).Line(field.Pos())
				line = line - 1
				// if tag for field doesn't exists, create one
				if field.Tag == nil {
					name := field.Names[0].String()
					if debug {
						fmt.Printf("Replacing line %s \n ", lines[line])
					}
					lines[line] = fmt.Sprintf("%s %v `%s:\"%s\"`", name, field.Type, tagName, ToSnake(name))
					if debug {
						fmt.Printf("By line : %s \n", lines[line])
					}
				} else if !strings.Contains(field.Tag.Value, fmt.Sprintf("%s:", tagName)) {
					// if tag exists, but doesn't contain target tag
					name := field.Names[0].String()
					if debug {
						fmt.Printf("Replacing line %s \n ", lines[line])
					}
					lines[line] = fmt.Sprintf("%s %v `%s:\"%s\" %s`", name, field.Type, tagName, ToSnake(name), strings.Replace(field.Tag.Value, "`", "", 2))
					if debug {
						fmt.Printf("By line : %s \n", lines[line])
					}

				}

			}
		}
	}
	// overwrite the file with modified version of lines.
	writeLines(lines, args[0])
	cmd := exec.Command("go", "fmt", args[0])
	cmd.Run()
}

// readLines reads a whole file into memory
// and returns a slice of its lines.
// original source : http://stackoverflow.com/questions/5884154/golang-read-text-file-into-string-array-and-write
func readLines(path string) ([]string, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var lines []string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines, scanner.Err()
}

// writeLines writes the lines to the given file.
func writeLines(lines []string, path string) error {
	file, err := os.Create(path)
	if err != nil {
		return err
	}
	defer file.Close()

	w := bufio.NewWriter(file)
	for _, line := range lines {
		fmt.Fprintln(w, line)
	}
	return w.Flush()
}

// ToSnake convert the given string to snake case following the Golang format:
// acronyms are converted to lower-case and preceded by an underscore.
// Original source : https://gist.github.com/elwinar/14e1e897fdbe4d3432e1
func ToSnake(in string) string {
	runes := []rune(in)
	length := len(runes)

	var out []rune
	for i := 0; i < length; i++ {
		if i > 0 && unicode.IsUpper(runes[i]) && ((i+1 < length && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1])) {
			out = append(out, '_')
		}
		out = append(out, unicode.ToLower(runes[i]))
	}

	return string(out)
}
<|endoftext|>


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

package net

import (
	"context"
	"syscall"
)

// BUG(mikio): On NaCl, Plan 9 and Windows, the ReadMsgUDP and
// WriteMsgUDP methods of UDPConn are not implemented.

// BUG(mikio): On Windows, the File method of UDPConn is not
// implemented.

// BUG(mikio): On NaCl, the ListenMulticastUDP function is not
// implemented.

// UDPAddr represents the address of a UDP end point.
type UDPAddr struct {
	IP   IP
	Port int
	Zone string // IPv6 scoped addressing zone
}

// Network returns the address's network name, "udp".
func (a *UDPAddr) Network() string { return "udp" }

func (a *UDPAddr) String() string {
	if a == nil {
		return "<nil>"
	}
	ip := ipEmptyString(a.IP)
	if a.Zone != "" {
		return JoinHostPort(ip+"%"+a.Zone, itoa(a.Port))
	}
	return JoinHostPort(ip, itoa(a.Port))
}

func (a *UDPAddr) isWildcard() bool {
	if a == nil || a.IP == nil {
		return true
	}
	return a.IP.IsUnspecified()
}

func (a *UDPAddr) opAddr() Addr {
	if a == nil {
		return nil
	}
	return a
}

// ResolveUDPAddr returns an address of UDP end point.
//
// The network must be a UDP network name.
//
// If the host in the address parameter is not a literal IP address or
// the port is not a literal port number, ResolveUDPAddr resolves the
// address to an address of UDP end point.
// Otherwise, it parses the address as a pair of literal IP address
// and port number.
// The address parameter can use a host name, but this is not
// recommended, because it will return at most one of the host name's
// IP addresses.
//
// See func Dial for a description of the network and address
// parameters.
func ResolveUDPAddr(network, address string) (*UDPAddr, error) {
	switch network {
	case "udp", "udp4", "udp6":
	case "": // a hint wildcard for Go 1.0 undocumented behavior
		network = "udp"
	default:
		return nil, UnknownNetworkError(network)
	}
	addrs, err := DefaultResolver.internetAddrList(context.Background(), network, address)
	if err != nil {
		return nil, err
	}
	return addrs.first(isIPv4).(*UDPAddr), nil
}

// UDPConn is the implementation of the Conn and PacketConn interfaces
// for UDP network connections.
type UDPConn struct {
	conn
}

// SyscallConn returns a raw network connection.
// This implements the syscall.Conn interface.
func (c *UDPConn) SyscallConn() (syscall.RawConn, error) {
	if !c.ok() {
		return nil, syscall.EINVAL
	}
	return newRawConn(c.fd)
}

// ReadFromUDP reads a UDP packet from c, copying the payload into b.
// It returns the number of bytes copied into b and the return address
// that was on the packet.
//
// ReadFromUDP can be made to time out and return an error with
// Timeout() == true after a fixed time limit; see SetDeadline and
// SetReadDeadline.
func (c *UDPConn) ReadFromUDP(b []byte) (int, *UDPAddr, error) {
	if !c.ok() {
		return 0, nil, syscall.EINVAL
	}
	n, addr, err := c.readFrom(b)
	if err != nil {
		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
	}
	return n, addr, err
}

// ReadFrom implements the PacketConn ReadFrom method.
func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) {
	if !c.ok() {
		return 0, nil, syscall.EINVAL
	}
	n, addr, err := c.readFrom(b)
	if err != nil {
		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
	}
	if addr == nil {
		return n, nil, err
	}
	return n, addr, err
}

// ReadMsgUDP reads a packet from c, copying the payload into b and
// the associated out-of-band data into oob. It returns the number
// of bytes copied into b, the number of bytes copied into oob, the
// flags that were set on the packet and the source address of the
// packet.
func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
	if !c.ok() {
		return 0, 0, 0, nil, syscall.EINVAL
	}
	n, oobn, flags, addr, err = c.readMsg(b, oob)
	if err != nil {
		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
	}
	return
}

// WriteToUDP writes a UDP packet to addr via c, copying the payload
// from b.
//
// WriteToUDP can be made to time out and return an error with
// Timeout() == true after a fixed time limit; see SetDeadline and
// SetWriteDeadline. On packet-oriented connections, write timeouts
// are rare.
func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
	if !c.ok() {
		return 0, syscall.EINVAL
	}
	n, err := c.writeTo(b, addr)
	if err != nil {
		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
	}
	return n, err
}

// WriteTo implements the PacketConn WriteTo method.
func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
	if !c.ok() {
		return 0, syscall.EINVAL
	}
	a, ok := addr.(*UDPAddr)
	if !ok {
		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
	}
	n, err := c.writeTo(b, a)
	if err != nil {
		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
	}
	return n, err
}

// WriteMsgUDP writes a packet to addr via c if c isn't connected, or
// to c's remote destination address if c is connected (in which case
// addr must be nil).  The payload is copied from b and the associated
// out-of-band data is copied from oob. It returns the number of
// payload and out-of-band bytes written.
func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
	if !c.ok() {
		return 0, 0, syscall.EINVAL
	}
	n, oobn, err = c.writeMsg(b, oob, addr)
	if err != nil {
		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
	}
	return
}

func newUDPConn(fd *netFD) *UDPConn { return &UDPConn{conn{fd}} }

// DialUDP acts like Dial for UDP networks.
//
// The network must be a UDP network name; see func Dial for details.
//
// If laddr is nil, a local address is automatically chosen.
// If the IP field of raddr is nil or an unspecified IP address, the
// local system is assumed.
func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error) {
	switch network {
	case "udp", "udp4", "udp6":
	default:
		return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
	}
	if raddr == nil {
		return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
	}
	c, err := dialUDP(context.Background(), network, laddr, raddr)
	if err != nil {
		return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
	}
	return c, nil
}

// ListenUDP acts like ListenPacket for UDP networks.
//
// The network must be a UDP network name; see func Dial for details.
//
// If the IP field of laddr is nil or an unspecified IP address,
// ListenUDP listens on all available IP addresses of the local system
// except multicast IP addresses.
// If the Port field of laddr is 0, a port number is automatically
// chosen.
func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error) {
	switch network {
	case "udp", "udp4", "udp6":
	default:
		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
	}
	if laddr == nil {
		laddr = &UDPAddr{}
	}
	c, err := listenUDP(context.Background(), network, laddr)
	if err != nil {
		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
	}
	return c, nil
}

// ListenMulticastUDP acts like ListenPacket for UDP networks but
// takes a group address on a specific network interface.
//
// The network must be a UDP network name; see func Dial for details.
//
// ListenMulticastUDP listens on all available IP addresses of the
// local system including the group, multicast IP address.
// If ifi is nil, ListenMulticastUDP uses the system-assigned
// multicast interface, although this is not recommended because the
// assignment depends on platforms and sometimes it might require
// routing configuration.
// If the Port field of gaddr is 0, a port number is automatically
// chosen.
//
// ListenMulticastUDP is just for convenience of simple, small
// applications. There are golang.org/x/net/ipv4 and
// golang.org/x/net/ipv6 packages for general purpose uses.
func ListenMulticastUDP(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
	switch network {
	case "udp", "udp4", "udp6":
	default:
		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: UnknownNetworkError(network)}
	}
	if gaddr == nil || gaddr.IP == nil {
		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: errMissingAddress}
	}
	c, err := listenMulticastUDP(context.Background(), network, ifi, gaddr)
	if err != nil {
		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: err}
	}
	return c, nil
}
<commit_msg>net: update documentation on methods of UDPConn<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package net

import (
	"context"
	"syscall"
)

// BUG(mikio): On NaCl, Plan 9 and Windows, the ReadMsgUDP and
// WriteMsgUDP methods of UDPConn are not implemented.

// BUG(mikio): On Windows, the File method of UDPConn is not
// implemented.

// BUG(mikio): On NaCl, the ListenMulticastUDP function is not
// implemented.

// UDPAddr represents the address of a UDP end point.
type UDPAddr struct {
	IP   IP
	Port int
	Zone string // IPv6 scoped addressing zone
}

// Network returns the address's network name, "udp".
func (a *UDPAddr) Network() string { return "udp" }

func (a *UDPAddr) String() string {
	if a == nil {
		return "<nil>"
	}
	ip := ipEmptyString(a.IP)
	if a.Zone != "" {
		return JoinHostPort(ip+"%"+a.Zone, itoa(a.Port))
	}
	return JoinHostPort(ip, itoa(a.Port))
}

func (a *UDPAddr) isWildcard() bool {
	if a == nil || a.IP == nil {
		return true
	}
	return a.IP.IsUnspecified()
}

func (a *UDPAddr) opAddr() Addr {
	if a == nil {
		return nil
	}
	return a
}

// ResolveUDPAddr returns an address of UDP end point.
//
// The network must be a UDP network name.
//
// If the host in the address parameter is not a literal IP address or
// the port is not a literal port number, ResolveUDPAddr resolves the
// address to an address of UDP end point.
// Otherwise, it parses the address as a pair of literal IP address
// and port number.
// The address parameter can use a host name, but this is not
// recommended, because it will return at most one of the host name's
// IP addresses.
//
// See func Dial for a description of the network and address
// parameters.
func ResolveUDPAddr(network, address string) (*UDPAddr, error) {
	switch network {
	case "udp", "udp4", "udp6":
	case "": // a hint wildcard for Go 1.0 undocumented behavior
		network = "udp"
	default:
		return nil, UnknownNetworkError(network)
	}
	addrs, err := DefaultResolver.internetAddrList(context.Background(), network, address)
	if err != nil {
		return nil, err
	}
	return addrs.first(isIPv4).(*UDPAddr), nil
}

// UDPConn is the implementation of the Conn and PacketConn interfaces
// for UDP network connections.
type UDPConn struct {
	conn
}

// SyscallConn returns a raw network connection.
// This implements the syscall.Conn interface.
func (c *UDPConn) SyscallConn() (syscall.RawConn, error) {
	if !c.ok() {
		return nil, syscall.EINVAL
	}
	return newRawConn(c.fd)
}

// ReadFromUDP acts like ReadFrom but returns a UDPAddr.
func (c *UDPConn) ReadFromUDP(b []byte) (int, *UDPAddr, error) {
	if !c.ok() {
		return 0, nil, syscall.EINVAL
	}
	n, addr, err := c.readFrom(b)
	if err != nil {
		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
	}
	return n, addr, err
}

// ReadFrom implements the PacketConn ReadFrom method.
func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) {
	if !c.ok() {
		return 0, nil, syscall.EINVAL
	}
	n, addr, err := c.readFrom(b)
	if err != nil {
		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
	}
	if addr == nil {
		return n, nil, err
	}
	return n, addr, err
}

// ReadMsgUDP reads a message from c, copying the payload into b and
// the associated out-of-band data into oob. It returns the number of
// bytes copied into b, the number of bytes copied into oob, the flags
// that were set on the message and the source address of the message.
//
// The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be
// used to manipulate IP-level socket options in oob.
func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
	if !c.ok() {
		return 0, 0, 0, nil, syscall.EINVAL
	}
	n, oobn, flags, addr, err = c.readMsg(b, oob)
	if err != nil {
		err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
	}
	return
}

// WriteToUDP acts like WriteTo but takes a UDPAddr.
func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
	if !c.ok() {
		return 0, syscall.EINVAL
	}
	n, err := c.writeTo(b, addr)
	if err != nil {
		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
	}
	return n, err
}

// WriteTo implements the PacketConn WriteTo method.
func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
	if !c.ok() {
		return 0, syscall.EINVAL
	}
	a, ok := addr.(*UDPAddr)
	if !ok {
		return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
	}
	n, err := c.writeTo(b, a)
	if err != nil {
		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
	}
	return n, err
}

// WriteMsgUDP writes a message to addr via c if c isn't connected, or
// to c's remote address if c is connected (in which case addr must be
// nil). The payload is copied from b and the associated out-of-band
// data is copied from oob. It returns the number of payload and
// out-of-band bytes written.
//
// The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be
// used to manipulate IP-level socket options in oob.
func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
	if !c.ok() {
		return 0, 0, syscall.EINVAL
	}
	n, oobn, err = c.writeMsg(b, oob, addr)
	if err != nil {
		err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
	}
	return
}

func newUDPConn(fd *netFD) *UDPConn { return &UDPConn{conn{fd}} }

// DialUDP acts like Dial for UDP networks.
//
// The network must be a UDP network name; see func Dial for details.
//
// If laddr is nil, a local address is automatically chosen.
// If the IP field of raddr is nil or an unspecified IP address, the
// local system is assumed.
func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error) {
	switch network {
	case "udp", "udp4", "udp6":
	default:
		return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
	}
	if raddr == nil {
		return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
	}
	c, err := dialUDP(context.Background(), network, laddr, raddr)
	if err != nil {
		return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
	}
	return c, nil
}

// ListenUDP acts like ListenPacket for UDP networks.
//
// The network must be a UDP network name; see func Dial for details.
//
// If the IP field of laddr is nil or an unspecified IP address,
// ListenUDP listens on all available IP addresses of the local system
// except multicast IP addresses.
// If the Port field of laddr is 0, a port number is automatically
// chosen.
func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error) {
	switch network {
	case "udp", "udp4", "udp6":
	default:
		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
	}
	if laddr == nil {
		laddr = &UDPAddr{}
	}
	c, err := listenUDP(context.Background(), network, laddr)
	if err != nil {
		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
	}
	return c, nil
}

// ListenMulticastUDP acts like ListenPacket for UDP networks but
// takes a group address on a specific network interface.
//
// The network must be a UDP network name; see func Dial for details.
//
// ListenMulticastUDP listens on all available IP addresses of the
// local system including the group, multicast IP address.
// If ifi is nil, ListenMulticastUDP uses the system-assigned
// multicast interface, although this is not recommended because the
// assignment depends on platforms and sometimes it might require
// routing configuration.
// If the Port field of gaddr is 0, a port number is automatically
// chosen.
//
// ListenMulticastUDP is just for convenience of simple, small
// applications. There are golang.org/x/net/ipv4 and
// golang.org/x/net/ipv6 packages for general purpose uses.
func ListenMulticastUDP(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
	switch network {
	case "udp", "udp4", "udp6":
	default:
		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: UnknownNetworkError(network)}
	}
	if gaddr == nil || gaddr.IP == nil {
		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: errMissingAddress}
	}
	c, err := listenMulticastUDP(context.Background(), network, ifi, gaddr)
	if err != nil {
		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: err}
	}
	return c, nil
}
<|endoftext|>


<commit_before>package rst

import (
	"bytes"
	"encoding"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"net/http"
	"reflect"
	"strings"
)

var alternatives = []string{
	"application/json",
	"text/javascript",
	"application/xml",
	"text/xml",
	"text/plain",
	"*/*",
}

/*
Marshaler is implemented by resources wishing to handle their encoding
on their own.

Example:
	const png = "image/png"

	type User struct{}
	// assuming User implements rst.Resource

	// MarshalREST returns the profile picture of the user if the Accept header
	// of the request indicates "image/png", and relies on rst.MarshalResource
	// to handle the other cases.
	func (u *User) MarshalREST(r *http.Request) (string, []byte, error) {
		accept := ParseAccept(r.Header.Get("Accept"))
		if accept.Negotiate(png) == png {
			b, err := ioutil.ReadFile("path/of/user/profile/picture.png")
			return png, b, err
		}
		return rst.MarshalResource(u, r)
	}
*/
type Marshaler interface {
	// MarshalREST must return the chosen encoding media MIME type and the
	// encoded resource as an array of bytes, or an error.
	//
	// MarshalREST is to rst.Marshal what MarshalJSON is to json.Marshal.
	MarshalREST(*http.Request) (contentType string, data []byte, err error)
}

// MarshalResource negotiates contentType based on the Accept header in r, and returns
// the encoded version of resource as an array of bytes.
//
// MarshalResource can encode a resource in JSON and XML, as well as text using either
// encoding.TextMarshaler or fmt.Stringer.
//
// MarshalResource's XML marshaling will always return a valid XML document with a
// header and a root object, which is not the case for the encoding/xml package.
//
// MarshalResource can be called from Marshaler.MarshalREST on the same resource safely.
func MarshalResource(resource interface{}, r *http.Request) (contentType string, encoded []byte, err error) {
	accept := ParseAccept(r.Header.Get("Accept"))
	if len(accept) == 0 {
		accept = append(accept, AcceptClause{
			Type:    "*",
			SubType: "*",
			Params:  make(map[string]string),
			Q:       1.0,
		})
	}

	switch accept.Negotiate(alternatives...) {
	case "application/json", "text/javascript", "*/*":
		b, err := json.Marshal(resource)
		return "application/json; charset=utf-8", b, err
	case "application/xml", "text/xml":
		b, err := marshalXML(resource)
		return "application/xml; charset=utf-8", b, err
	case "text/plain":
		if marshaler, implemented := resource.(encoding.TextMarshaler); implemented {
			b, err := marshaler.MarshalText()
			return "text/plain; charset=utf-8", b, err
		}
		if marshaler, implemented := resource.(fmt.Stringer); implemented {
			return "text/plain; charset=utf-8", []byte(marshaler.String()), nil
		}
	}
	return "", nil, NotAcceptable()
}

// marshalXML adds an XML header and an envelope when needed to the result
// obtained from calling xml.Marshal on resource.
func marshalXML(resource interface{}) ([]byte, error) {
	b, err := xml.Marshal(resource)
	if err != nil {
		return nil, err
	}
	if bytes.Equal(b[:len(xml.Header)], []byte(xml.Header)) {
		return b, err
	}

	// Arrays and slices need an envelope.
	if t := reflect.TypeOf(resource); t.Kind() == reflect.Array || t.Kind() == reflect.Slice {
		fqn := strings.Split(t.String(), ".")
		name := fqn[len(fqn)-1] + "List"
		prefix := []byte("<" + name + ">")
		suffix := []byte("</" + name + ">")
		b = bytes.Join([][]byte{prefix, b, suffix}, nil)
	}

	// Adding XML header
	b = bytes.Join([][]byte{[]byte(xml.Header), b}, nil)

	return b, err
}

// Marshal negotiates contentType based on the Accept header in r, and returns
// the encoded version of resource as an array of bytes.
//
// Marshal uses resource.MarshalREST if resource implements the Marshaler
// interface, or MarshalResource method if it doesn't.
func Marshal(resource interface{}, r *http.Request) (contentType string, encoded []byte, err error) {
	if marshaler, implemented := resource.(Marshaler); implemented {
		return marshaler.MarshalREST(r)
	}

	return MarshalResource(resource, r)
}
<commit_msg>Removed */* from the cases when negotiating a type<commit_after>package rst

import (
	"bytes"
	"encoding"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"net/http"
	"reflect"
	"strings"
)

var alternatives = []string{
	"application/json",
	"text/javascript",
	"application/xml",
	"text/xml",
	"text/plain",
	"*/*",
}

/*
Marshaler is implemented by resources wishing to handle their encoding
on their own.

Example:
	const png = "image/png"

	type User struct{}
	// assuming User implements rst.Resource

	// MarshalREST returns the profile picture of the user if the Accept header
	// of the request indicates "image/png", and relies on rst.MarshalResource
	// to handle the other cases.
	func (u *User) MarshalREST(r *http.Request) (string, []byte, error) {
		accept := ParseAccept(r.Header.Get("Accept"))
		if accept.Negotiate(png) == png {
			b, err := ioutil.ReadFile("path/of/user/profile/picture.png")
			return png, b, err
		}
		return rst.MarshalResource(u, r)
	}
*/
type Marshaler interface {
	// MarshalREST must return the chosen encoding media MIME type and the
	// encoded resource as an array of bytes, or an error.
	//
	// MarshalREST is to rst.Marshal what MarshalJSON is to json.Marshal.
	MarshalREST(*http.Request) (contentType string, data []byte, err error)
}

// MarshalResource negotiates contentType based on the Accept header in r, and returns
// the encoded version of resource as an array of bytes.
//
// MarshalResource can encode a resource in JSON and XML, as well as text using either
// encoding.TextMarshaler or fmt.Stringer.
//
// MarshalResource's XML marshaling will always return a valid XML document with a
// header and a root object, which is not the case for the encoding/xml package.
//
// MarshalResource can be called from Marshaler.MarshalREST on the same resource safely.
func MarshalResource(resource interface{}, r *http.Request) (contentType string, encoded []byte, err error) {
	accept := ParseAccept(r.Header.Get("Accept"))
	if len(accept) == 0 {
		accept = append(accept, AcceptClause{
			Type:    "*",
			SubType: "*",
			Params:  make(map[string]string),
			Q:       1.0,
		})
	}

	switch accept.Negotiate(alternatives...) {
	case "application/json", "text/javascript":
		b, err := json.Marshal(resource)
		return "application/json; charset=utf-8", b, err
	case "application/xml", "text/xml":
		b, err := marshalXML(resource)
		return "application/xml; charset=utf-8", b, err
	case "text/plain":
		if marshaler, implemented := resource.(encoding.TextMarshaler); implemented {
			b, err := marshaler.MarshalText()
			return "text/plain; charset=utf-8", b, err
		}
		if marshaler, implemented := resource.(fmt.Stringer); implemented {
			return "text/plain; charset=utf-8", []byte(marshaler.String()), nil
		}
	}
	return "", nil, NotAcceptable()
}

// marshalXML adds an XML header and an envelope when needed to the result
// obtained from calling xml.Marshal on resource.
func marshalXML(resource interface{}) ([]byte, error) {
	b, err := xml.Marshal(resource)
	if err != nil {
		return nil, err
	}
	if bytes.Equal(b[:len(xml.Header)], []byte(xml.Header)) {
		return b, err
	}

	// Arrays and slices need an envelope.
	if t := reflect.TypeOf(resource); t.Kind() == reflect.Array || t.Kind() == reflect.Slice {
		fqn := strings.Split(t.String(), ".")
		name := fqn[len(fqn)-1] + "List"
		prefix := []byte("<" + name + ">")
		suffix := []byte("</" + name + ">")
		b = bytes.Join([][]byte{prefix, b, suffix}, nil)
	}

	// Adding XML header
	b = bytes.Join([][]byte{[]byte(xml.Header), b}, nil)

	return b, err
}

// Marshal negotiates contentType based on the Accept header in r, and returns
// the encoded version of resource as an array of bytes.
//
// Marshal uses resource.MarshalREST if resource implements the Marshaler
// interface, or MarshalResource method if it doesn't.
func Marshal(resource interface{}, r *http.Request) (contentType string, encoded []byte, err error) {
	if marshaler, implemented := resource.(Marshaler); implemented {
		return marshaler.MarshalREST(r)
	}

	return MarshalResource(resource, r)
}
<|endoftext|>


<commit_before>package ncp

import (
	"regexp"
	"strconv"
	"strings"
)

func (t *Topic) getRating() float64 {
	var (
		reRating = regexp.MustCompile(`>(\d,\d|\d)<\/span>.+?\(Голосов:`)
		rating   float64
	)
	if reRating.Match(t.Body) == true {
		str := string(reRating.FindSubmatch(t.Body)[1])
		str = strings.Replace(str, ",", ".", -1)
		rating, _ = strconv.ParseFloat(str, 64)
	}
	return rating
}

func (t *Topic) getSize() int64 {
	var (
		reSize = regexp.MustCompile(`Размер блока: \d.+?B"> (\d{1,2},\d{1,2}|\d{3,4}|\d{1,2})\s`)
		size   int64
	)
	if reSize.Match(t.Body) == true {
		str := string(reSize.FindSubmatch(t.Body)[1])
		str = strings.Replace(str, ",", ".", -1)
		if s64, err := strconv.ParseFloat(str, 64); err == nil {
			if s64 < 100 {
				s64 = s64 * 1000
			}
			size = int64(s64)
		}
	}
	return size
}

func (t *Topic) getTorrent() string {
	var (
		reTor   = regexp.MustCompile(`<a href="download\.php\?id=(\d{5,7})" rel="nofollow">Скачать<`)
		torrent string
	)
	if reTor.Match(t.Body) == true {
		findTor := reTor.FindSubmatch(t.Body)
		torrent = string(findTor[1])
		// http://nnm-club.me/forum/download.php?id=
	}
	return torrent
}

func (t *Topic) getMagnet() string {
	var (
		reMag  = regexp.MustCompile(`href="magnet:\?xt=urn:btih:(.+?)(?:"|&)`)
		magnet string
	)
	if reMag.Match(t.Body) == true {
		findMag := reMag.FindSubmatch(t.Body)
		magnet = string(findMag[1])
		// magnet:?xt=urn:btih:
	}
	return magnet
}

func (t *Topic) getPoster() string {
	var (
		rePos = regexp.MustCompile(`"postImg postImgAligned img-right" title="http:\/\/assets\..*?\/forum\/image\.php\?link=(.+?jpe{0,1}g)`)
		image string
	)
	if rePos.Match(t.Body) == true {
		image = string(rePos.FindSubmatch(t.Body)[1])
	}
	return image
}

func (t *Topic) getDate() string {
	var (
		reDate = regexp.MustCompile(`> (\d{1,2} .{3} \d{4}).{9}<`)
		date   string
	)
	if reDate.Match(t.Body) == true {
		date = replaceDate(string(reDate.FindSubmatch(t.Body)[1]))
	}
	return date
}

func (t *Topic) getSeeds() int64 {
	var (
		reSs  = regexp.MustCompile(`<span class="seed">\[ <b>(\d{1,5})\s`)
		seeds int64
	)
	if reSs.Match(t.Body) == true {
		ss := reSs.FindSubmatch(t.Body)
		seeds, _ = strconv.ParseInt(string(ss[1]), 10, 64)
	}
	return seeds
}

func (t *Topic) getLeechs() int64 {
	var (
		reLs   = regexp.MustCompile(`<span class="leech">\[ <b>(\d{1,5})\s`)
		leechs int64
	)
	if reLs.Match(t.Body) == true {
		ls := reLs.FindSubmatch(t.Body)
		leechs, _ = strconv.ParseInt(string(ls[1]), 10, 64)
	}
	return leechs
}

func getResolution(str string) string {
	var (
		reRes      = regexp.MustCompile(`(\d{3,4}x\d{3,4}|\d{3,4}X\d{3,4}|\d{3,4}х\d{3,4}|\d{3,4}Х\d{3,4})`)
		resolution string
	)
	if reRes.MatchString(str) == true {
		resolution = reRes.FindString(str)
	}
	return resolution
}

func (t *Topic) getCountry() string {
	var (
		reCountry = regexp.MustCompile(`<span style="font-weight: bold">Производство:\s*<\/span>(.+?)<`)
		country   string
	)
	if reCountry.Match(t.Body) == true {
		country = string(reCountry.FindSubmatch(t.Body)[1])
		country = cleanStr(country)
	}
	return country
}

func (t *Topic) getGenre() string {
	var (
		reGenre = regexp.MustCompile(`<span style="font-weight: bold">Жанр:\s*<\/span>(.+?)<`)
		genre   string
	)
	if reGenre.Match(t.Body) == true {
		genre = string(reGenre.FindSubmatch(t.Body)[1])
		genre = strings.ToLower(cleanStr(genre))
		genre = strings.Trim(genre, ".")
	}
	return genre
}

func (t *Topic) getDirector() string {
	var (
		reDirector = regexp.MustCompile(`<span style="font-weight: bold">Режиссер:\s*<\/span>(.+?)<`)
		director   string
	)
	if reDirector.Match(t.Body) == true {
		director = string(reDirector.FindSubmatch(t.Body)[1])
		director = cleanStr(director)
		director = strings.Trim(director, ".")
	}
	return director
}

func (t *Topic) getProducer() string {
	var (
		reProducer = regexp.MustCompile(`<span style="font-weight: bold">Продюсер:\s*<\/span>(.+?)<`)
		producer   string
	)
	if reProducer.Match(t.Body) == true {
		producer = string(reProducer.FindSubmatch(t.Body)[1])
		producer = cleanStr(producer)
		producer = strings.Trim(producer, ".")
	}
	return producer
}

func (t *Topic) getActors() string {
	var (
		reActors = regexp.MustCompile(`<span style="font-weight: bold">Актеры:\s*<\/span>(.+?)<`)
		actors   string
	)
	if reActors.Match(t.Body) == true {
		actors = string(reActors.FindSubmatch(t.Body)[1])
		actors = cleanStr(actors)
		actors = strings.Trim(actors, ".")
	}
	return actors
}

func (t *Topic) getDescription() string {
	var (
		reDescription = regexp.MustCompile(`<span style="font-weight: bold">(?:Описание фильма|Описание):\s*<\/span>(.+?)<`)
		description   string
	)
	if reDescription.Match(t.Body) == true {
		description = string(reDescription.FindSubmatch(t.Body)[1])
		description = cleanStr(description)
	}
	return description
}

func (t *Topic) getAge() string {
	var (
		reAge = regexp.MustCompile(`<span style="font-weight: bold">Возраст:\s*<\/span>(.+?)<`)
		age   string
	)
	if reAge.Match(t.Body) == true {
		age = string(reAge.FindSubmatch(t.Body)[1])
		age = cleanStr(age)
	}
	return age
}

func (t *Topic) getReleaseDate() string {
	var (
		reReleaseDate = regexp.MustCompile(`<span style="font-weight: bold">Дата мировой премьеры:\s*<\/span>(.+?)<`)
		releaseDate   string
	)
	if reReleaseDate.Match(t.Body) == true {
		releaseDate = string(reReleaseDate.FindSubmatch(t.Body)[1])
		releaseDate = cleanStr(releaseDate)
		releaseDate = replaceDate(releaseDate)
	}
	return releaseDate
}

func (t *Topic) getRussianDate() string {
	var (
		reRussianDate = regexp.MustCompile(`<span style="font-weight: bold">(?:Дата премьеры в России|Дата Российской премьеры|Дата российской премьеры):\s*<\/span>(.+?)<`)
		russianDate   string
	)
	if reRussianDate.Match(t.Body) == true {
		russianDate = string(reRussianDate.FindSubmatch(t.Body)[1])
		russianDate = cleanStr(russianDate)
		russianDate = replaceDate(russianDate)
	}
	return russianDate
}

func (t *Topic) getDuration() string {
	var (
		reDuration = regexp.MustCompile(`<span style="font-weight: bold">Продолжительность:\s*<\/span>(.+?)<`)
		duration   string
	)
	if reDuration.Match(t.Body) == true {
		duration = string(reDuration.FindSubmatch(t.Body)[1])
		duration = cleanStr(duration)
	} else {
		reDuration = regexp.MustCompile(`\sПродолжительность\s+?: (\d{1,2}) ч\. (\d{1,2}) м\.`)
		if reDuration.Match(t.Body) == true {
			submatch := reDuration.FindSubmatch(t.Body)
			hour := string(submatch[1])
			minute := string(submatch[2])
			if len(hour) == 1 {
				hour = "0" + hour
			}
			if len(minute) == 1 {
				minute = "0" + minute
			}
			duration = hour + ":" + minute + ":00"
		}
	}
	if len(duration) < 5 {
		duration = ""
	}
	return duration
}

func (t *Topic) getQuality() string {
	var (
		reQuality = regexp.MustCompile(`<span style="font-weight: bold">(?:Качество видео|Качество):\s*<\/span>(.+?)<`)
		quality   string
	)
	if reQuality.Match(t.Body) == true {
		quality = string(reQuality.FindSubmatch(t.Body)[1])
		quality = cleanStr(quality)
	}
	return quality
}

func (t *Topic) getTranslation() string {
	var (
		reTranslation = regexp.MustCompile(`<span style="font-weight: bold">Перевод:\s*<\/span>(.+?)<`)
		translation   string
	)
	translation = "Не требуется"
	if reTranslation.Match(t.Body) == true {
		translation = string(reTranslation.FindSubmatch(t.Body)[1])
		translation = cleanStr(translation)
	}
	return translation
}

func (t *Topic) getSubtitlesType() string {
	var (
		reSubtitlesType = regexp.MustCompile(`<span style="font-weight: bold">Вид субтитров:\s*<\/span>(.+?)<`)
		subtitlesType   string
	)
	if reSubtitlesType.Match(t.Body) == true {
		subtitlesType = string(reSubtitlesType.FindSubmatch(t.Body)[1])
		subtitlesType = cleanStr(subtitlesType)
	}
	return subtitlesType
}

func (t *Topic) getSubtitles() string {
	var (
		reSubtitles = regexp.MustCompile(`<span style="font-weight: bold">Субтитры:\s*<\/span>(.+?)<`)
		subtitles   string
	)
	if reSubtitles.Match(t.Body) == true {
		subtitles = string(reSubtitles.FindSubmatch(t.Body)[1])
		subtitles = cleanStr(subtitles)
	}
	return subtitles
}

func (t *Topic) getVideo() string {
	var (
		reVideo = regexp.MustCompile(`<span style="font-weight: bold">Видео:\s*<\/span>(.+?)<`)
		video   string
	)
	if reVideo.Match(t.Body) == true {
		video = string(reVideo.FindSubmatch(t.Body)[1])
		video = cleanStr(video)
	}
	return video
}

func (t *Topic) getAudio1() string {
	var (
		reAudio = regexp.MustCompile(`<span style="font-weight: bold">(?:Аудио\s?:\s*|Аудио\s?.?1.?:\s*)<\/span>(.+?)<`)
		audio   string
	)
	if reAudio.Match(t.Body) == true {
		audio = string(reAudio.FindSubmatch(t.Body)[1])
		audio = cleanStr(audio)
	}
	return audio
}

func (t *Topic) getAudio2() string {
	var (
		reAudio = regexp.MustCompile(`<span style="font-weight: bold">Аудио\s?.?2.?:\s*<\/span>(.+?)<`)
		audio   string
	)
	if reAudio.Match(t.Body) == true {
		audio = string(reAudio.FindSubmatch(t.Body)[1])
		audio = cleanStr(audio)
	}
	return audio
}

func (t *Topic) getAudio3() string {
	var (
		reAudio = regexp.MustCompile(`<span style="font-weight: bold">Аудио\s?.?3.?:\s*<\/span>(.+?)<`)
		audio   string
	)
	if reAudio.Match(t.Body) == true {
		audio = string(reAudio.FindSubmatch(t.Body)[1])
		audio = cleanStr(audio)
	}
	return audio
}
<commit_msg>add png to parse poster<commit_after>package ncp

import (
	"regexp"
	"strconv"
	"strings"
)

func (t *Topic) getRating() float64 {
	var (
		reRating = regexp.MustCompile(`>(\d,\d|\d)<\/span>.+?\(Голосов:`)
		rating   float64
	)
	if reRating.Match(t.Body) == true {
		str := string(reRating.FindSubmatch(t.Body)[1])
		str = strings.Replace(str, ",", ".", -1)
		rating, _ = strconv.ParseFloat(str, 64)
	}
	return rating
}

func (t *Topic) getSize() int64 {
	var (
		reSize = regexp.MustCompile(`Размер блока: \d.+?B"> (\d{1,2},\d{1,2}|\d{3,4}|\d{1,2})\s`)
		size   int64
	)
	if reSize.Match(t.Body) == true {
		str := string(reSize.FindSubmatch(t.Body)[1])
		str = strings.Replace(str, ",", ".", -1)
		if s64, err := strconv.ParseFloat(str, 64); err == nil {
			if s64 < 100 {
				s64 = s64 * 1000
			}
			size = int64(s64)
		}
	}
	return size
}

func (t *Topic) getTorrent() string {
	var (
		reTor   = regexp.MustCompile(`<a href="download\.php\?id=(\d{5,7})" rel="nofollow">Скачать<`)
		torrent string
	)
	if reTor.Match(t.Body) == true {
		findTor := reTor.FindSubmatch(t.Body)
		torrent = string(findTor[1])
		// http://nnm-club.me/forum/download.php?id=
	}
	return torrent
}

func (t *Topic) getMagnet() string {
	var (
		reMag  = regexp.MustCompile(`href="magnet:\?xt=urn:btih:(.+?)(?:"|&)`)
		magnet string
	)
	if reMag.Match(t.Body) == true {
		findMag := reMag.FindSubmatch(t.Body)
		magnet = string(findMag[1])
		// magnet:?xt=urn:btih:
	}
	return magnet
}

func (t *Topic) getPoster() string {
	var (
		rePos = regexp.MustCompile(`"postImg postImgAligned img-right" title="http:\/\/assets\..*?\/forum\/image\.php\?link=(.+?(?:jpg|jpeg|png))"`)
		image string
	)
	if rePos.Match(t.Body) == true {
		image = string(rePos.FindSubmatch(t.Body)[1])
	}
	return image
}

func (t *Topic) getDate() string {
	var (
		reDate = regexp.MustCompile(`> (\d{1,2} .{3} \d{4}).{9}<`)
		date   string
	)
	if reDate.Match(t.Body) == true {
		date = replaceDate(string(reDate.FindSubmatch(t.Body)[1]))
	}
	return date
}

func (t *Topic) getSeeds() int64 {
	var (
		reSs  = regexp.MustCompile(`<span class="seed">\[ <b>(\d{1,5})\s`)
		seeds int64
	)
	if reSs.Match(t.Body) == true {
		ss := reSs.FindSubmatch(t.Body)
		seeds, _ = strconv.ParseInt(string(ss[1]), 10, 64)
	}
	return seeds
}

func (t *Topic) getLeechs() int64 {
	var (
		reLs   = regexp.MustCompile(`<span class="leech">\[ <b>(\d{1,5})\s`)
		leechs int64
	)
	if reLs.Match(t.Body) == true {
		ls := reLs.FindSubmatch(t.Body)
		leechs, _ = strconv.ParseInt(string(ls[1]), 10, 64)
	}
	return leechs
}

func getResolution(str string) string {
	var (
		reRes      = regexp.MustCompile(`(\d{3,4}x\d{3,4}|\d{3,4}X\d{3,4}|\d{3,4}х\d{3,4}|\d{3,4}Х\d{3,4})`)
		resolution string
	)
	if reRes.MatchString(str) == true {
		resolution = reRes.FindString(str)
	}
	return resolution
}

func (t *Topic) getCountry() string {
	var (
		reCountry = regexp.MustCompile(`<span style="font-weight: bold">Производство:\s*<\/span>(.+?)<`)
		country   string
	)
	if reCountry.Match(t.Body) == true {
		country = string(reCountry.FindSubmatch(t.Body)[1])
		country = cleanStr(country)
	}
	return country
}

func (t *Topic) getGenre() string {
	var (
		reGenre = regexp.MustCompile(`<span style="font-weight: bold">Жанр:\s*<\/span>(.+?)<`)
		genre   string
	)
	if reGenre.Match(t.Body) == true {
		genre = string(reGenre.FindSubmatch(t.Body)[1])
		genre = strings.ToLower(cleanStr(genre))
		genre = strings.Trim(genre, ".")
	}
	return genre
}

func (t *Topic) getDirector() string {
	var (
		reDirector = regexp.MustCompile(`<span style="font-weight: bold">Режиссер:\s*<\/span>(.+?)<`)
		director   string
	)
	if reDirector.Match(t.Body) == true {
		director = string(reDirector.FindSubmatch(t.Body)[1])
		director = cleanStr(director)
		director = strings.Trim(director, ".")
	}
	return director
}

func (t *Topic) getProducer() string {
	var (
		reProducer = regexp.MustCompile(`<span style="font-weight: bold">Продюсер:\s*<\/span>(.+?)<`)
		producer   string
	)
	if reProducer.Match(t.Body) == true {
		producer = string(reProducer.FindSubmatch(t.Body)[1])
		producer = cleanStr(producer)
		producer = strings.Trim(producer, ".")
	}
	return producer
}

func (t *Topic) getActors() string {
	var (
		reActors = regexp.MustCompile(`<span style="font-weight: bold">Актеры:\s*<\/span>(.+?)<`)
		actors   string
	)
	if reActors.Match(t.Body) == true {
		actors = string(reActors.FindSubmatch(t.Body)[1])
		actors = cleanStr(actors)
		actors = strings.Trim(actors, ".")
	}
	return actors
}

func (t *Topic) getDescription() string {
	var (
		reDescription = regexp.MustCompile(`<span style="font-weight: bold">(?:Описание фильма|Описание):\s*<\/span>(.+?)<`)
		description   string
	)
	if reDescription.Match(t.Body) == true {
		description = string(reDescription.FindSubmatch(t.Body)[1])
		description = cleanStr(description)
	}
	return description
}

func (t *Topic) getAge() string {
	var (
		reAge = regexp.MustCompile(`<span style="font-weight: bold">Возраст:\s*<\/span>(.+?)<`)
		age   string
	)
	if reAge.Match(t.Body) == true {
		age = string(reAge.FindSubmatch(t.Body)[1])
		age = cleanStr(age)
	}
	return age
}

func (t *Topic) getReleaseDate() string {
	var (
		reReleaseDate = regexp.MustCompile(`<span style="font-weight: bold">Дата мировой премьеры:\s*<\/span>(.+?)<`)
		releaseDate   string
	)
	if reReleaseDate.Match(t.Body) == true {
		releaseDate = string(reReleaseDate.FindSubmatch(t.Body)[1])
		releaseDate = cleanStr(releaseDate)
		releaseDate = replaceDate(releaseDate)
	}
	return releaseDate
}

func (t *Topic) getRussianDate() string {
	var (
		reRussianDate = regexp.MustCompile(`<span style="font-weight: bold">(?:Дата премьеры в России|Дата Российской премьеры|Дата российской премьеры):\s*<\/span>(.+?)<`)
		russianDate   string
	)
	if reRussianDate.Match(t.Body) == true {
		russianDate = string(reRussianDate.FindSubmatch(t.Body)[1])
		russianDate = cleanStr(russianDate)
		russianDate = replaceDate(russianDate)
	}
	return russianDate
}

func (t *Topic) getDuration() string {
	var (
		reDuration = regexp.MustCompile(`<span style="font-weight: bold">Продолжительность:\s*<\/span>(.+?)<`)
		duration   string
	)
	if reDuration.Match(t.Body) == true {
		duration = string(reDuration.FindSubmatch(t.Body)[1])
		duration = cleanStr(duration)
	} else {
		reDuration = regexp.MustCompile(`\sПродолжительность\s+?: (\d{1,2}) ч\. (\d{1,2}) м\.`)
		if reDuration.Match(t.Body) == true {
			submatch := reDuration.FindSubmatch(t.Body)
			hour := string(submatch[1])
			minute := string(submatch[2])
			if len(hour) == 1 {
				hour = "0" + hour
			}
			if len(minute) == 1 {
				minute = "0" + minute
			}
			duration = hour + ":" + minute + ":00"
		}
	}
	if len(duration) < 5 {
		duration = ""
	}
	return duration
}

func (t *Topic) getQuality() string {
	var (
		reQuality = regexp.MustCompile(`<span style="font-weight: bold">(?:Качество видео|Качество):\s*<\/span>(.+?)<`)
		quality   string
	)
	if reQuality.Match(t.Body) == true {
		quality = string(reQuality.FindSubmatch(t.Body)[1])
		quality = cleanStr(quality)
	}
	return quality
}

func (t *Topic) getTranslation() string {
	var (
		reTranslation = regexp.MustCompile(`<span style="font-weight: bold">Перевод:\s*<\/span>(.+?)<`)
		translation   string
	)
	translation = "Не требуется"
	if reTranslation.Match(t.Body) == true {
		translation = string(reTranslation.FindSubmatch(t.Body)[1])
		translation = cleanStr(translation)
	}
	return translation
}

func (t *Topic) getSubtitlesType() string {
	var (
		reSubtitlesType = regexp.MustCompile(`<span style="font-weight: bold">Вид субтитров:\s*<\/span>(.+?)<`)
		subtitlesType   string
	)
	if reSubtitlesType.Match(t.Body) == true {
		subtitlesType = string(reSubtitlesType.FindSubmatch(t.Body)[1])
		subtitlesType = cleanStr(subtitlesType)
	}
	return subtitlesType
}

func (t *Topic) getSubtitles() string {
	var (
		reSubtitles = regexp.MustCompile(`<span style="font-weight: bold">Субтитры:\s*<\/span>(.+?)<`)
		subtitles   string
	)
	if reSubtitles.Match(t.Body) == true {
		subtitles = string(reSubtitles.FindSubmatch(t.Body)[1])
		subtitles = cleanStr(subtitles)
	}
	return subtitles
}

func (t *Topic) getVideo() string {
	var (
		reVideo = regexp.MustCompile(`<span style="font-weight: bold">Видео:\s*<\/span>(.+?)<`)
		video   string
	)
	if reVideo.Match(t.Body) == true {
		video = string(reVideo.FindSubmatch(t.Body)[1])
		video = cleanStr(video)
	}
	return video
}

func (t *Topic) getAudio1() string {
	var (
		reAudio = regexp.MustCompile(`<span style="font-weight: bold">(?:Аудио\s?:\s*|Аудио\s?.?1.?:\s*)<\/span>(.+?)<`)
		audio   string
	)
	if reAudio.Match(t.Body) == true {
		audio = string(reAudio.FindSubmatch(t.Body)[1])
		audio = cleanStr(audio)
	}
	return audio
}

func (t *Topic) getAudio2() string {
	var (
		reAudio = regexp.MustCompile(`<span style="font-weight: bold">Аудио\s?.?2.?:\s*<\/span>(.+?)<`)
		audio   string
	)
	if reAudio.Match(t.Body) == true {
		audio = string(reAudio.FindSubmatch(t.Body)[1])
		audio = cleanStr(audio)
	}
	return audio
}

func (t *Topic) getAudio3() string {
	var (
		reAudio = regexp.MustCompile(`<span style="font-weight: bold">Аудио\s?.?3.?:\s*<\/span>(.+?)<`)
		audio   string
	)
	if reAudio.Match(t.Body) == true {
		audio = string(reAudio.FindSubmatch(t.Body)[1])
		audio = cleanStr(audio)
	}
	return audio
}
<|endoftext|>


<commit_before>package zego

func (a Auth) ListViews() (*Resource, error) {

	path := "/views.json"
	resource, err := api(a, "GET", path, "")
	if err != nil {
		return nil, err
	}

	return resource, nil

}
<commit_msg>Added views struct<commit_after>package zego

View struct {
    Id           int `json:"id"`
    Title        string `json:"title"`
    Active       bool `json:"active"`
    SlaId        int `json:"sla_id"`
    Execution    []interface{} `json:"execution"`
    Conditions   []interface{} `json:"conditions"`
    Restriction  *Restriction `json:"restriction"`
}

Restriction  struct {
    Type         string `json:"type"`
    Id           int `json:"id"`
}

func (a Auth) ListViews() (*Resource, error) {

	path := "/views.json"
	resource, err := api(a, "GET", path, "")
	if err != nil {
		return nil, err
	}

	return resource, nil

}
<|endoftext|>


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

package wire

import (
	"sync/atomic"
	"testing"
	"time"
)

func TestPeriodicTask(t *testing.T) {
	var callCount int32
	values := make(chan int32)
	task := func() {
		values <- atomic.AddInt32(&callCount, 1)
	}
	ptask := newPeriodicTask(10*time.Millisecond, task)

	t.Run("Start1", func(t *testing.T) {
		ptask.Start()
		ptask.Start() // Tests duplicate start

		if got, want := <-values, int32(1); got != want {
			t.Errorf("got %d, want %d", got, want)
		}
	})

	t.Run("Stop1", func(t *testing.T) {
		ptask.Stop()
		ptask.Stop() // Tests duplicate stop

		select {
		case got := <-values:
			t.Errorf("got unexpected value %d", got)
		default:
		}
	})

	t.Run("Start2", func(t *testing.T) {
		ptask.Start()

		if got, want := <-values, int32(2); got != want {
			t.Errorf("got %d, want %d", got, want)
		}
	})

	t.Run("Stop2", func(t *testing.T) {
		ptask.Stop()

		select {
		case got := <-values:
			t.Errorf("got unexpected value %d", got)
		default:
		}
	})
}
<commit_msg>test(pubsublite): fix flaky TestPeriodicTask (#4069)<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and

package wire

import (
	"sync/atomic"
	"testing"
	"time"
)

func TestPeriodicTask(t *testing.T) {
	const pollInterval = 10 * time.Millisecond
	var callCount int32
	values := make(chan int32)
	task := func() {
		values <- atomic.AddInt32(&callCount, 1)
	}
	ptask := newPeriodicTask(pollInterval, task)
	defer ptask.Stop()

	t.Run("Start", func(t *testing.T) {
		ptask.Start()
		ptask.Start() // Tests duplicate start

		got := <-values

		// Attempt to immediately stop the task after the first run.
		// Note: if this test is still flaky, pollInterval can be increased.
		ptask.Stop()

		if want := int32(1); got != want {
			t.Errorf("got %d, want %d", got, want)
		}
	})

	t.Run("Stop", func(t *testing.T) {
		ptask.Stop() // Tests duplicate stop (also called in Start above)

		// Wait at least the poll interval to ensure the task did not run.
		time.Sleep(2 * pollInterval)
		select {
		case got := <-values:
			t.Errorf("got unexpected value %d", got)
		default:
		}
	})

	t.Run("Restart", func(t *testing.T) {
		ptask.Start()

		if got, want := <-values, int32(2); got != want {
			t.Errorf("got %d, want %d", got, want)
		}
	})
}
<|endoftext|>


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

package search

import (
	"encoding/json"
	"fmt"
	"github.com/mattbaird/elastigo/api"
	"github.com/mattbaird/elastigo/core"
	"log"
	"strings"

	u "github.com/araddon/gou"
)

var (
	_ = u.DEBUG
)

// Search is the entry point to the SearchDsl, it is a chainable set of utilities
// to create searches.
//
// params
//    @index = elasticsearch index to search
//
//    out, err := Search("github").Type("Issues").Pretty().Query(
//    Query().Range(
//         Range().Field("created_at").From("2012-12-10T15:00:00-08:00").To("2012-12-10T15:10:00-08:00"),
//       ).Search("add"),
//     ).Result()
func Search(index string) *SearchDsl {
	return &SearchDsl{Index: index, args: map[string]interface{}{}}
}

type SearchDsl struct {
	args          map[string]interface{}
	types         []string
	FromVal       int                      `json:"from,omitempty"`
	SizeVal       int                      `json:"size,omitempty"`
	Index         string                   `json:"-"`
	FacetVal      *FacetDsl                `json:"facets,omitempty"`
	QueryVal      *QueryDsl                `json:"query,omitempty"`
	SortBody      []*SortDsl               `json:"sort,omitempty"`
	FilterVal     *FilterWrap              `json:"filter,omitempty"`
	AggregatesVal map[string]*AggregateDsl `json:"aggregates,omitempty"`
}

func (s *SearchDsl) Bytes() ([]byte, error) {
	return api.DoCommand("POST", s.url(), s.args, s)
}

func (s *SearchDsl) Result() (*core.SearchResult, error) {
	var retval core.SearchResult
	if core.DebugRequests {
		sb, _ := json.MarshalIndent(s, "  ", "  ")
		log.Println(s.url())
		log.Println(string(sb))
	}
	body, err := s.Bytes()
	if err != nil {
		u.Errorf("%v", err)
		return nil, err
	}
	jsonErr := json.Unmarshal(body, &retval)
	if jsonErr != nil {
		u.Errorf("%v \n\t%s", jsonErr, string(body))
	}
	//Debug(string(body))
	return &retval, jsonErr
}

func (s *SearchDsl) url() string {
	url := fmt.Sprintf("/%s%s/_search", s.Index, s.getType())
	return url
}

func (s *SearchDsl) Pretty() *SearchDsl {
	s.args["pretty"] = "1"
	return s
}

// Type is the elasticsearch *Type* within a specific index
func (s *SearchDsl) Type(indexType string) *SearchDsl {
	if len(s.types) == 0 {
		s.types = make([]string, 0)
	}
	s.types = append(s.types, indexType)
	return s
}

func (s *SearchDsl) getType() string {
	if len(s.types) > 0 {
		return "/" + strings.Join(s.types, ",")
	}
	return ""
}

func (s *SearchDsl) From(from string) *SearchDsl {
	s.args["from"] = from
	return s
}

// Search is a simple interface to search, doesn't have the power of query
// but uses a simple query_string search
func (s *SearchDsl) Search(srch string) *SearchDsl {
	s.QueryVal = Query().Search(srch)
	return s
}

func (s *SearchDsl) Size(size string) *SearchDsl {
	s.args["size"] = size
	return s
}

// Facet passes a Query expression to this search
//
//		qry := Search("github").Size("0").Facet(
//					Facet().Regex("repository.name", "no.*").Size("8"),
//				)
//
//		qry := Search("github").Pretty().Facet(
//					Facet().Fields("type").Size("25"),
//				)
func (s *SearchDsl) Facet(f *FacetDsl) *SearchDsl {
	s.FacetVal = f
	return s
}

func (s *SearchDsl) Aggregates(aggs ...*AggregateDsl) *SearchDsl {
	if len(aggs) < 1 {
		return s
	}
	if len(s.AggregatesVal) == 0 {
		s.AggregatesVal = make(map[string]*AggregateDsl)
	}

	for _, agg := range aggs {
		s.AggregatesVal[agg.Name] = agg
	}
	return s
}

func (s *SearchDsl) Query(q *QueryDsl) *SearchDsl {
	s.QueryVal = q
	return s
}

// Filter adds a Filter Clause with optional Boolean Clause.  This accepts n number of
// filter clauses.  If more than one, and missing Boolean Clause it assumes "and"
//
//     qry := Search("github").Filter(
//         Filter().Exists("repository.name"),
//     )
//
//     qry := Search("github").Filter(
//         "or",
//         Filter().Exists("repository.name"),
//         Filter().Terms("actor_attributes.location", "portland"),
//     )
//
//     qry := Search("github").Filter(
//         Filter().Exists("repository.name"),
//         Filter().Terms("repository.has_wiki", true)
//     )
func (s *SearchDsl) Filter(fl ...interface{}) *SearchDsl {
	if s.FilterVal == nil {
		s.FilterVal = NewFilterWrap()
	}

	s.FilterVal.addFilters(fl)
	return s
}

func (s *SearchDsl) Sort(sort ...*SortDsl) *SearchDsl {
	if s.SortBody == nil {
		s.SortBody = make([]*SortDsl, 0)
	}
	s.SortBody = append(s.SortBody, sort...)
	return s
}
<commit_msg>Use correct aggregation key<commit_after>// Copyright 2013 Matthew Baird
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//     http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package search

import (
	"encoding/json"
	"fmt"
	"github.com/mattbaird/elastigo/api"
	"github.com/mattbaird/elastigo/core"
	"log"
	"strings"

	u "github.com/araddon/gou"
)

var (
	_ = u.DEBUG
)

// Search is the entry point to the SearchDsl, it is a chainable set of utilities
// to create searches.
//
// params
//    @index = elasticsearch index to search
//
//    out, err := Search("github").Type("Issues").Pretty().Query(
//    Query().Range(
//         Range().Field("created_at").From("2012-12-10T15:00:00-08:00").To("2012-12-10T15:10:00-08:00"),
//       ).Search("add"),
//     ).Result()
func Search(index string) *SearchDsl {
	return &SearchDsl{Index: index, args: map[string]interface{}{}}
}

type SearchDsl struct {
	args          map[string]interface{}
	types         []string
	FromVal       int                      `json:"from,omitempty"`
	SizeVal       int                      `json:"size,omitempty"`
	Index         string                   `json:"-"`
	FacetVal      *FacetDsl                `json:"facets,omitempty"`
	QueryVal      *QueryDsl                `json:"query,omitempty"`
	SortBody      []*SortDsl               `json:"sort,omitempty"`
	FilterVal     *FilterWrap              `json:"filter,omitempty"`
	AggregatesVal map[string]*AggregateDsl `json:"aggregations,omitempty"`
}

func (s *SearchDsl) Bytes() ([]byte, error) {
	return api.DoCommand("POST", s.url(), s.args, s)
}

func (s *SearchDsl) Result() (*core.SearchResult, error) {
	var retval core.SearchResult
	if core.DebugRequests {
		sb, _ := json.MarshalIndent(s, "  ", "  ")
		log.Println(s.url())
		log.Println(string(sb))
	}
	body, err := s.Bytes()
	if err != nil {
		u.Errorf("%v", err)
		return nil, err
	}
	jsonErr := json.Unmarshal(body, &retval)
	if jsonErr != nil {
		u.Errorf("%v \n\t%s", jsonErr, string(body))
	}
	//Debug(string(body))
	return &retval, jsonErr
}

func (s *SearchDsl) url() string {
	url := fmt.Sprintf("/%s%s/_search", s.Index, s.getType())
	return url
}

func (s *SearchDsl) Pretty() *SearchDsl {
	s.args["pretty"] = "1"
	return s
}

// Type is the elasticsearch *Type* within a specific index
func (s *SearchDsl) Type(indexType string) *SearchDsl {
	if len(s.types) == 0 {
		s.types = make([]string, 0)
	}
	s.types = append(s.types, indexType)
	return s
}

func (s *SearchDsl) getType() string {
	if len(s.types) > 0 {
		return "/" + strings.Join(s.types, ",")
	}
	return ""
}

func (s *SearchDsl) From(from string) *SearchDsl {
	s.args["from"] = from
	return s
}

// Search is a simple interface to search, doesn't have the power of query
// but uses a simple query_string search
func (s *SearchDsl) Search(srch string) *SearchDsl {
	s.QueryVal = Query().Search(srch)
	return s
}

func (s *SearchDsl) Size(size string) *SearchDsl {
	s.args["size"] = size
	return s
}

// Facet passes a Query expression to this search
//
//		qry := Search("github").Size("0").Facet(
//					Facet().Regex("repository.name", "no.*").Size("8"),
//				)
//
//		qry := Search("github").Pretty().Facet(
//					Facet().Fields("type").Size("25"),
//				)
func (s *SearchDsl) Facet(f *FacetDsl) *SearchDsl {
	s.FacetVal = f
	return s
}

func (s *SearchDsl) Aggregates(aggs ...*AggregateDsl) *SearchDsl {
	if len(aggs) < 1 {
		return s
	}
	if len(s.AggregatesVal) == 0 {
		s.AggregatesVal = make(map[string]*AggregateDsl)
	}

	for _, agg := range aggs {
		s.AggregatesVal[agg.Name] = agg
	}
	return s
}

func (s *SearchDsl) Query(q *QueryDsl) *SearchDsl {
	s.QueryVal = q
	return s
}

// Filter adds a Filter Clause with optional Boolean Clause.  This accepts n number of
// filter clauses.  If more than one, and missing Boolean Clause it assumes "and"
//
//     qry := Search("github").Filter(
//         Filter().Exists("repository.name"),
//     )
//
//     qry := Search("github").Filter(
//         "or",
//         Filter().Exists("repository.name"),
//         Filter().Terms("actor_attributes.location", "portland"),
//     )
//
//     qry := Search("github").Filter(
//         Filter().Exists("repository.name"),
//         Filter().Terms("repository.has_wiki", true)
//     )
func (s *SearchDsl) Filter(fl ...interface{}) *SearchDsl {
	if s.FilterVal == nil {
		s.FilterVal = NewFilterWrap()
	}

	s.FilterVal.addFilters(fl)
	return s
}

func (s *SearchDsl) Sort(sort ...*SortDsl) *SearchDsl {
	if s.SortBody == nil {
		s.SortBody = make([]*SortDsl, 0)
	}
	s.SortBody = append(s.SortBody, sort...)
	return s
}
<|endoftext|>


<commit_before>package serial

import (
	"fmt"
	"time"
)

var errNotImplemented = fmt.Errorf("not implemented")

type port struct {
}

func New() {
	return &port{}
}

func (_ *port) Open(*Config) error {
	return errNotImplemented
}

func (_ *port) Read([]byte) (int, error) {
	return 0, errNotImplemented
}

func (_ *port) Write([]byte) (int, error) {
	return 0, errNotImplemented
}

func (_ *port) Close() error {
	return errNotImplemented
}
<commit_msg>Fix build on Mac<commit_after>package serial

import (
	"fmt"
)

var errNotImplemented = fmt.Errorf("not implemented")

type port struct {
}

func New() Port {
	return &port{}
}

func (_ *port) Open(*Config) error {
	return errNotImplemented
}

func (_ *port) Read([]byte) (int, error) {
	return 0, errNotImplemented
}

func (_ *port) Write([]byte) (int, error) {
	return 0, errNotImplemented
}

func (_ *port) Close() error {
	return errNotImplemented
}
<|endoftext|>


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

package ct

import (
	"crypto"
	"encoding/json"
	"fmt"
	"strings"

	"github.com/google/certificate-transparency-go/tls"
)

// SerializeSCTSignatureInput serializes the passed in sct and log entry into
// the correct format for signing.
func SerializeSCTSignatureInput(sct SignedCertificateTimestamp, entry LogEntry) ([]byte, error) {
	switch sct.SCTVersion {
	case V1:
		input := CertificateTimestamp{
			SCTVersion:    sct.SCTVersion,
			SignatureType: CertificateTimestampSignatureType,
			Timestamp:     sct.Timestamp,
			EntryType:     entry.Leaf.TimestampedEntry.EntryType,
			Extensions:    sct.Extensions,
		}
		switch entry.Leaf.TimestampedEntry.EntryType {
		case X509LogEntryType:
			input.X509Entry = entry.Leaf.TimestampedEntry.X509Entry
		case PrecertLogEntryType:
			input.PrecertEntry = &PreCert{
				IssuerKeyHash:  entry.Leaf.TimestampedEntry.PrecertEntry.IssuerKeyHash,
				TBSCertificate: entry.Leaf.TimestampedEntry.PrecertEntry.TBSCertificate,
			}
		case XJSONLogEntryType:
			input.JSONEntry = entry.Leaf.TimestampedEntry.JSONEntry
		default:
			return nil, fmt.Errorf("unsupported entry type %s", entry.Leaf.TimestampedEntry.EntryType)
		}
		return tls.Marshal(input)
	default:
		return nil, fmt.Errorf("unknown SCT version %d", sct.SCTVersion)
	}
}

// SerializeSTHSignatureInput serializes the passed in STH into the correct
// format for signing.
func SerializeSTHSignatureInput(sth SignedTreeHead) ([]byte, error) {
	switch sth.Version {
	case V1:
		if len(sth.SHA256RootHash) != crypto.SHA256.Size() {
			return nil, fmt.Errorf("invalid TreeHash length, got %d expected %d", len(sth.SHA256RootHash), crypto.SHA256.Size())
		}

		input := TreeHeadSignature{
			Version:        sth.Version,
			SignatureType:  TreeHashSignatureType,
			Timestamp:      sth.Timestamp,
			TreeSize:       sth.TreeSize,
			SHA256RootHash: sth.SHA256RootHash,
		}
		return tls.Marshal(input)
	default:
		return nil, fmt.Errorf("unsupported STH version %d", sth.Version)
	}
}

// CreateX509MerkleTreeLeaf generates a MerkleTreeLeaf for an X509 cert
func CreateX509MerkleTreeLeaf(cert ASN1Cert, timestamp uint64) *MerkleTreeLeaf {
	return &MerkleTreeLeaf{
		Version:  V1,
		LeafType: TimestampedEntryLeafType,
		TimestampedEntry: &TimestampedEntry{
			Timestamp: timestamp,
			EntryType: X509LogEntryType,
			X509Entry: &cert,
		},
	}
}

// CreateJSONMerkleTreeLeaf creates the merkle tree leaf for json data.
func CreateJSONMerkleTreeLeaf(data interface{}, timestamp uint64) *MerkleTreeLeaf {
	jsonData, err := json.Marshal(AddJSONRequest{Data: data})
	if err != nil {
		return nil
	}
	// Match the JSON serialization implemented by json-c
	jsonStr := strings.Replace(string(jsonData), ":", ": ", -1)
	jsonStr = strings.Replace(jsonStr, ",", ", ", -1)
	jsonStr = strings.Replace(jsonStr, "{", "{ ", -1)
	jsonStr = strings.Replace(jsonStr, "}", " }", -1)
	jsonStr = strings.Replace(jsonStr, "/", `\/`, -1)
	// TODO: Pending google/certificate-transparency#1243, replace with
	// ObjectHash once supported by CT server.

	return &MerkleTreeLeaf{
		Version:  V1,
		LeafType: TimestampedEntryLeafType,
		TimestampedEntry: &TimestampedEntry{
			Timestamp: timestamp,
			EntryType: XJSONLogEntryType,
			JSONEntry: &JSONDataEntry{Data: []byte(jsonStr)},
		},
	}
}
<commit_msg>ct: add MerkleLeafFrom[Raw]Chain() function<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ct

import (
	"crypto"
	"crypto/sha256"
	"encoding/json"
	"fmt"
	"strings"

	"github.com/google/certificate-transparency-go/tls"
	"github.com/google/certificate-transparency-go/x509"
	"github.com/google/certificate-transparency-go/x509/pkix"
)

// SerializeSCTSignatureInput serializes the passed in sct and log entry into
// the correct format for signing.
func SerializeSCTSignatureInput(sct SignedCertificateTimestamp, entry LogEntry) ([]byte, error) {
	switch sct.SCTVersion {
	case V1:
		input := CertificateTimestamp{
			SCTVersion:    sct.SCTVersion,
			SignatureType: CertificateTimestampSignatureType,
			Timestamp:     sct.Timestamp,
			EntryType:     entry.Leaf.TimestampedEntry.EntryType,
			Extensions:    sct.Extensions,
		}
		switch entry.Leaf.TimestampedEntry.EntryType {
		case X509LogEntryType:
			input.X509Entry = entry.Leaf.TimestampedEntry.X509Entry
		case PrecertLogEntryType:
			input.PrecertEntry = &PreCert{
				IssuerKeyHash:  entry.Leaf.TimestampedEntry.PrecertEntry.IssuerKeyHash,
				TBSCertificate: entry.Leaf.TimestampedEntry.PrecertEntry.TBSCertificate,
			}
		case XJSONLogEntryType:
			input.JSONEntry = entry.Leaf.TimestampedEntry.JSONEntry
		default:
			return nil, fmt.Errorf("unsupported entry type %s", entry.Leaf.TimestampedEntry.EntryType)
		}
		return tls.Marshal(input)
	default:
		return nil, fmt.Errorf("unknown SCT version %d", sct.SCTVersion)
	}
}

// SerializeSTHSignatureInput serializes the passed in STH into the correct
// format for signing.
func SerializeSTHSignatureInput(sth SignedTreeHead) ([]byte, error) {
	switch sth.Version {
	case V1:
		if len(sth.SHA256RootHash) != crypto.SHA256.Size() {
			return nil, fmt.Errorf("invalid TreeHash length, got %d expected %d", len(sth.SHA256RootHash), crypto.SHA256.Size())
		}

		input := TreeHeadSignature{
			Version:        sth.Version,
			SignatureType:  TreeHashSignatureType,
			Timestamp:      sth.Timestamp,
			TreeSize:       sth.TreeSize,
			SHA256RootHash: sth.SHA256RootHash,
		}
		return tls.Marshal(input)
	default:
		return nil, fmt.Errorf("unsupported STH version %d", sth.Version)
	}
}

// CreateX509MerkleTreeLeaf generates a MerkleTreeLeaf for an X509 cert
func CreateX509MerkleTreeLeaf(cert ASN1Cert, timestamp uint64) *MerkleTreeLeaf {
	return &MerkleTreeLeaf{
		Version:  V1,
		LeafType: TimestampedEntryLeafType,
		TimestampedEntry: &TimestampedEntry{
			Timestamp: timestamp,
			EntryType: X509LogEntryType,
			X509Entry: &cert,
		},
	}
}

// CreateJSONMerkleTreeLeaf creates the merkle tree leaf for json data.
func CreateJSONMerkleTreeLeaf(data interface{}, timestamp uint64) *MerkleTreeLeaf {
	jsonData, err := json.Marshal(AddJSONRequest{Data: data})
	if err != nil {
		return nil
	}
	// Match the JSON serialization implemented by json-c
	jsonStr := strings.Replace(string(jsonData), ":", ": ", -1)
	jsonStr = strings.Replace(jsonStr, ",", ", ", -1)
	jsonStr = strings.Replace(jsonStr, "{", "{ ", -1)
	jsonStr = strings.Replace(jsonStr, "}", " }", -1)
	jsonStr = strings.Replace(jsonStr, "/", `\/`, -1)
	// TODO: Pending google/certificate-transparency#1243, replace with
	// ObjectHash once supported by CT server.

	return &MerkleTreeLeaf{
		Version:  V1,
		LeafType: TimestampedEntryLeafType,
		TimestampedEntry: &TimestampedEntry{
			Timestamp: timestamp,
			EntryType: XJSONLogEntryType,
			JSONEntry: &JSONDataEntry{Data: []byte(jsonStr)},
		},
	}
}

// MerkleTreeLeafFromRawChain generates a MerkleTreeLeaf from a chain (in DER-encoded form) and timestamp.
func MerkleTreeLeafFromRawChain(rawChain []ASN1Cert, etype LogEntryType, timestamp uint64) (*MerkleTreeLeaf, error) {
	// Need at most 3 of the chain
	count := 3
	if count > len(rawChain) {
		count = len(rawChain)
	}
	chain := make([]*x509.Certificate, count)
	for i := range chain {
		cert, err := x509.ParseCertificate(rawChain[i].Data)
		if err != nil {
			return nil, fmt.Errorf("failed to parse chain[%d] cert: %v", i, err)
		}
		chain[i] = cert
	}
	return MerkleTreeLeafFromChain(chain, etype, timestamp)
}

// MerkleTreeLeafFromChain generates a MerkleTreeLeaf from a chain and timestamp.
func MerkleTreeLeafFromChain(chain []*x509.Certificate, etype LogEntryType, timestamp uint64) (*MerkleTreeLeaf, error) {
	leaf := MerkleTreeLeaf{
		Version:  V1,
		LeafType: TimestampedEntryLeafType,
		TimestampedEntry: &TimestampedEntry{
			EntryType: etype,
			Timestamp: timestamp,
		},
	}
	if etype == X509LogEntryType {
		leaf.TimestampedEntry.X509Entry = &ASN1Cert{Data: chain[0].Raw}
		return &leaf, nil
	}
	if etype != PrecertLogEntryType {
		return nil, fmt.Errorf("unknown LogEntryType %d", etype)
	}

	// Pre-certs are more complicated. First, parse the leaf pre-cert and its
	// putative issuer.
	if len(chain) < 2 {
		return nil, fmt.Errorf("no issuer cert available for precert leaf building")
	}
	issuer := chain[1]
	cert := chain[0]

	var issuerName *pkix.Name
	if IsPreIssuer(issuer) {
		// The issuer of the pre-cert is not going to be the issuer of the final
		// cert.  Change to use the final issuer.
		if len(chain) < 3 {
			return nil, fmt.Errorf("no issuer cert available for pre-issuer")
		}
		issuer = chain[2]

		// Replace the cert's Issuer field with the Subject from the
		// intermediate that will sign the final cert.
		issuerName = &issuer.Subject
	}

	// Next, post-process the DER-encoded TBSCertificate, to remove the CT poison
	// extension and possibly update the issuer field.
	defangedTBS, err := x509.BuildPrecertTBS(cert.RawTBSCertificate, issuerName)
	if err != nil {
		return nil, fmt.Errorf("failed to remove poison extension: %v", err)
	}

	leaf.TimestampedEntry.EntryType = PrecertLogEntryType
	leaf.TimestampedEntry.PrecertEntry = &PreCert{
		IssuerKeyHash:  sha256.Sum256(issuer.RawSubjectPublicKeyInfo),
		TBSCertificate: defangedTBS,
	}
	return &leaf, nil
}

// IsPreIssuer indicates whether a certificate is a pre-cert issuer with the specific
// certificate transparency extended key usage.
func IsPreIssuer(issuer *x509.Certificate) bool {
	for _, eku := range issuer.ExtKeyUsage {
		if eku == x509.ExtKeyUsageCertificateTransparency {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package wats

import (
	"crypto/tls"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"

	"github.com/cloudfoundry-incubator/cf-test-helpers/helpers"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("File ACLs", func() {

	var inaccessibleFiles = []string{
		"C:\\bosh",
		"C:\\containerizer",
		"C:\\var",
		"C:\\Windows\\Panther\\Unattend",
	}

	var client = &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

	BeforeEach(func() {
		pushAndStartNora(appName)
		Eventually(helpers.CurlingAppRoot(config, appName)).Should(ContainSubstring("hello i am nora"))
	})

	permission := func(path string) (string, error) {
		uri := helpers.AppUri(appName, "/inaccessible_file", config)
		res, err := client.Post(uri, "text/plain", strings.NewReader(path))
		if err != nil {
			return "", err
		}
		defer res.Body.Close()
		body, err := ioutil.ReadAll(res.Body)
		return string(body), err
	}

	It("A Container user should not have permission to view sensitive files", func() {
		for _, path := range inaccessibleFiles {
			response, err := permission(path)
			Expect(err).To(Succeed(), path)

			response, err = strconv.Unquote(response)
			Expect(err).To(Succeed())
			Expect(response).To(Or(Equal("ACCESS_DENIED"), Equal("NOT_EXIST")), path)
		}
	})
})
<commit_msg>file ACLs not applicable on windows2016<commit_after>package wats

import (
	"crypto/tls"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"

	"github.com/cloudfoundry-incubator/cf-test-helpers/helpers"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("File ACLs", func() {

	var inaccessibleFiles = []string{
		"C:\\bosh",
		"C:\\containerizer",
		"C:\\var",
		"C:\\Windows\\Panther\\Unattend",
	}

	var client = &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

	BeforeEach(func() {
		if config.GetStack() == "windows2016" {
			Skip("n/a on windows2016")
		}

		pushAndStartNora(appName)
		Eventually(helpers.CurlingAppRoot(config, appName)).Should(ContainSubstring("hello i am nora"))
	})

	permission := func(path string) (string, error) {
		uri := helpers.AppUri(appName, "/inaccessible_file", config)
		res, err := client.Post(uri, "text/plain", strings.NewReader(path))
		if err != nil {
			return "", err
		}
		defer res.Body.Close()
		body, err := ioutil.ReadAll(res.Body)
		return string(body), err
	}

	It("A Container user should not have permission to view sensitive files", func() {
		for _, path := range inaccessibleFiles {
			response, err := permission(path)
			Expect(err).To(Succeed(), path)

			response, err = strconv.Unquote(response)
			Expect(err).To(Succeed())
			Expect(response).To(Or(Equal("ACCESS_DENIED"), Equal("NOT_EXIST")), path)
		}
	})
})
<|endoftext|>


<commit_before>package server

import (
	"os"
	"path"
	"sync/atomic"
	"time"

	"github.com/coreos/etcd/clientv3"
	storagepb "github.com/coreos/etcd/storage/storagepb"
	"github.com/golang/protobuf/proto"
	"github.com/juju/errors"
	"github.com/ngaut/log"
	"github.com/pingcap/kvproto/pkg/pdpb"
	"golang.org/x/net/context"
)

// IsLeader returns whether server is leader or not.
func (s *Server) IsLeader() bool {
	return atomic.LoadInt64(&s.isLeader) == 1
}

func (s *Server) enableLeader(b bool) {
	value := int64(0)
	if b {
		value = 1
	}

	atomic.StoreInt64(&s.isLeader, value)

	if !b {
		// if we lost leader, we may:
		//	1, close all client connections
		//	2, close all running raft clusters
		s.closeAllConnections()

		s.cluster.Stop()
	}
}

func (s *Server) getLeaderPath() string {
	return path.Join(s.rootPath, "leader")
}

func (s *Server) leaderLoop() {
	defer func() {
		s.wg.Done()
		s.enableLeader(false)
	}()

	for {
		if s.IsClosed() {
			return
		}

		s.enableLeader(false)

		leader, err := s.getLeader()
		if err != nil {
			log.Errorf("get leader err %v", err)
			continue
		} else if leader != nil {
			log.Debugf("leader is %s, watch it", leader)

			s.watchLeader()

			log.Debug("leader changed, try to campaign leader")
		}

		if err = s.campaignLeader(); err != nil {
			log.Errorf("campaign leader err %s", err)
		}
	}
}

// GetLeader gets server leader from etcd.
func GetLeader(c *clientv3.Client, leaderPath string) (*pdpb.Leader, error) {
	leader := pdpb.Leader{}
	ok, err := getProtoMsg(c, leaderPath, &leader)
	if err != nil || !ok {
		return nil, errors.Trace(err)
	}

	return &leader, nil
}

func (s *Server) getLeader() (*pdpb.Leader, error) {
	return GetLeader(s.client, s.getLeaderPath())
}

func (s *Server) marshalLeader() string {
	leader := &pdpb.Leader{
		Addr: proto.String(s.cfg.AdvertiseAddr),
		Pid:  proto.Int64(int64(os.Getpid())),
	}

	data, err := proto.Marshal(leader)
	if err != nil {
		// can't fail, so panic here.
		log.Fatalf("marshal leader %s err %v", leader, err)
	}

	return string(data)
}

func (s *Server) campaignLeader() error {
	log.Debug("begin to campaign leader")

	lessor := clientv3.NewLease(s.client)
	defer lessor.Close()

	ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
	leaseResp, err := lessor.Grant(ctx, s.cfg.LeaderLease)
	cancel()
	if err != nil {
		return errors.Trace(err)
	}

	leaderKey := s.getLeaderPath()
	// The leader key must not exist, so the CreateRevision is 0.
	ctx, cancel = context.WithTimeout(context.Background(), requestTimeout)
	resp, err := s.client.Txn(ctx).
		If(clientv3.Compare(clientv3.CreateRevision(leaderKey), "=", 0)).
		Then(clientv3.OpPut(leaderKey, s.leaderValue, clientv3.WithLease(clientv3.LeaseID(leaseResp.ID)))).
		Commit()
	cancel()
	if err != nil {
		return errors.Trace(err)
	}
	if !resp.Succeeded {
		return errors.New("campaign leader failed, other server may campaign ok")
	}

	log.Debug("campaign leader ok")
	s.enableLeader(true)
	defer s.enableLeader(false)

	// keeps the leader
	ch, err := lessor.KeepAlive(s.client.Ctx(), clientv3.LeaseID(leaseResp.ID))
	if err != nil {
		return errors.Trace(err)
	}

	log.Debug("sync timestamp for tso")
	if err = s.syncTimestamp(); err != nil {
		return errors.Trace(err)
	}

	tsTicker := time.NewTicker(time.Duration(updateTimestampStep) * time.Millisecond)
	defer tsTicker.Stop()

	for {
		select {
		case _, ok := <-ch:
			if !ok {
				log.Info("keep alive channel is closed")
				return nil
			}
		case <-tsTicker.C:
			if err = s.updateTimestamp(); err != nil {
				return errors.Trace(err)
			}
		}
	}
}

func (s *Server) watchLeader() {
	watcher := clientv3.NewWatcher(s.client)
	defer watcher.Close()

	for {
		rch := watcher.Watch(s.client.Ctx(), s.getLeaderPath())
		for wresp := range rch {
			if wresp.Canceled {
				return
			}

			for _, ev := range wresp.Events {
				if ev.Type == storagepb.EXPIRE || ev.Type == storagepb.DELETE {
					log.Info("leader is expired or deleted")
					return
				}
			}
		}
	}
}

func (s *Server) leaderCmp() clientv3.Cmp {
	return clientv3.Compare(clientv3.Value(s.getLeaderPath()), "=", s.leaderValue)
}
<commit_msg>leader: Sleep for a while if get leader failed.<commit_after>package server

import (
	"os"
	"path"
	"sync/atomic"
	"time"

	"github.com/coreos/etcd/clientv3"
	storagepb "github.com/coreos/etcd/storage/storagepb"
	"github.com/golang/protobuf/proto"
	"github.com/juju/errors"
	"github.com/ngaut/log"
	"github.com/pingcap/kvproto/pkg/pdpb"
	"golang.org/x/net/context"
)

// IsLeader returns whether server is leader or not.
func (s *Server) IsLeader() bool {
	return atomic.LoadInt64(&s.isLeader) == 1
}

func (s *Server) enableLeader(b bool) {
	value := int64(0)
	if b {
		value = 1
	}

	atomic.StoreInt64(&s.isLeader, value)

	if !b {
		// if we lost leader, we may:
		//	1, close all client connections
		//	2, close all running raft clusters
		s.closeAllConnections()

		s.cluster.Stop()
	}
}

func (s *Server) getLeaderPath() string {
	return path.Join(s.rootPath, "leader")
}

func (s *Server) leaderLoop() {
	defer func() {
		s.wg.Done()
		s.enableLeader(false)
	}()

	for {
		if s.IsClosed() {
			return
		}

		s.enableLeader(false)

		leader, err := s.getLeader()
		if err != nil {
			log.Errorf("get leader err %v", err)
			time.Sleep(200 * time.Millisecond)
			continue
		} else if leader != nil {
			log.Infof("leader is %s, watch it", leader)
			s.watchLeader()
			log.Info("leader changed, try to campaign leader")
		}

		if err = s.campaignLeader(); err != nil {
			log.Errorf("campaign leader err %s", err)
		}
	}
}

// GetLeader gets server leader from etcd.
func GetLeader(c *clientv3.Client, leaderPath string) (*pdpb.Leader, error) {
	leader := pdpb.Leader{}
	ok, err := getProtoMsg(c, leaderPath, &leader)
	if err != nil || !ok {
		return nil, errors.Trace(err)
	}

	return &leader, nil
}

func (s *Server) getLeader() (*pdpb.Leader, error) {
	return GetLeader(s.client, s.getLeaderPath())
}

func (s *Server) marshalLeader() string {
	leader := &pdpb.Leader{
		Addr: proto.String(s.cfg.AdvertiseAddr),
		Pid:  proto.Int64(int64(os.Getpid())),
	}

	data, err := proto.Marshal(leader)
	if err != nil {
		// can't fail, so panic here.
		log.Fatalf("marshal leader %s err %v", leader, err)
	}

	return string(data)
}

func (s *Server) campaignLeader() error {
	log.Debug("begin to campaign leader")

	lessor := clientv3.NewLease(s.client)
	defer lessor.Close()

	ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
	leaseResp, err := lessor.Grant(ctx, s.cfg.LeaderLease)
	cancel()
	if err != nil {
		return errors.Trace(err)
	}

	leaderKey := s.getLeaderPath()
	// The leader key must not exist, so the CreateRevision is 0.
	ctx, cancel = context.WithTimeout(context.Background(), requestTimeout)
	resp, err := s.client.Txn(ctx).
		If(clientv3.Compare(clientv3.CreateRevision(leaderKey), "=", 0)).
		Then(clientv3.OpPut(leaderKey, s.leaderValue, clientv3.WithLease(clientv3.LeaseID(leaseResp.ID)))).
		Commit()
	cancel()
	if err != nil {
		return errors.Trace(err)
	}
	if !resp.Succeeded {
		return errors.New("campaign leader failed, other server may campaign ok")
	}

	log.Debug("campaign leader ok")
	s.enableLeader(true)
	defer s.enableLeader(false)

	// keeps the leader
	ch, err := lessor.KeepAlive(s.client.Ctx(), clientv3.LeaseID(leaseResp.ID))
	if err != nil {
		return errors.Trace(err)
	}

	log.Debug("sync timestamp for tso")
	if err = s.syncTimestamp(); err != nil {
		return errors.Trace(err)
	}

	tsTicker := time.NewTicker(time.Duration(updateTimestampStep) * time.Millisecond)
	defer tsTicker.Stop()

	for {
		select {
		case _, ok := <-ch:
			if !ok {
				log.Info("keep alive channel is closed")
				return nil
			}
		case <-tsTicker.C:
			if err = s.updateTimestamp(); err != nil {
				return errors.Trace(err)
			}
		}
	}
}

func (s *Server) watchLeader() {
	watcher := clientv3.NewWatcher(s.client)
	defer watcher.Close()

	for {
		rch := watcher.Watch(s.client.Ctx(), s.getLeaderPath())
		for wresp := range rch {
			if wresp.Canceled {
				return
			}

			for _, ev := range wresp.Events {
				if ev.Type == storagepb.EXPIRE || ev.Type == storagepb.DELETE {
					log.Info("leader is expired or deleted")
					return
				}
			}
		}
	}
}

func (s *Server) leaderCmp() clientv3.Cmp {
	return clientv3.Compare(clientv3.Value(s.getLeaderPath()), "=", s.leaderValue)
}
<|endoftext|>


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

package server

import (
	"net/http"
	"strings"
)

type route struct {
	pathPrefix string
	handler    func(http.ResponseWriter, *http.Request)
}

type router struct {
	routes []*route
}

func newRouter() *router {
	return &router{}
}

func (h *router) HandleFunc(pathPrefix string, handler func(http.ResponseWriter, *http.Request)) {
	r := &route{pathPrefix, handler}
	h.routes = append(h.routes, r)
}

func (h *router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	for _, route := range h.routes {
		if strings.HasPrefix(r.URL.Path, route.pathPrefix) {
			route.handler(w, r)
			break
		}
	}
}
<commit_msg>Updating to App Engine 1.9.0.<commit_after>// Copyright 2013 Richard lincoln All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package server

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

type route struct {
	pathPrefix string
	handler    func(http.ResponseWriter, *http.Request)
}

type router struct {
	routes []*route
}

func newRouter() *router {
	return &router{}
}

func (h *router) HandleFunc(pathPrefix string, handler func(http.ResponseWriter, *http.Request)) {
	r := &route{pathPrefix, handler}
	h.routes = append(h.routes, r)
}

// Routes the request if it matches one of our reserved URLs. This also
// handles OPTIONS CORS requests.
func (h *router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	for _, route := range h.routes {
		if strings.HasPrefix(r.URL.Path, route.pathPrefix) {
			route.handler(w, r)
			return
		}
	}

	if r.Method == "OPTIONS" {
		corsHandler := newCheckCorsHeaders(r)
		if corsHandler.allowCorsRequest {
			// The server returns 200 rather than 204, for some reason.
			corsHandler.updateHeaders(w.Header())
			w.WriteHeader(http.StatusOK)
			fmt.Fprint(w, "")
		}
	}
}
<|endoftext|>