<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 pe implements access to PE (Microsoft Windows Portable Executable) files.
package pe

import (
	"debug/dwarf"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"os"
	"strconv"
	"unsafe"
)

// A File represents an open PE file.
type File struct {
	FileHeader
	OptionalHeader interface{} // of type *OptionalHeader32 or *OptionalHeader64
	Sections       []*Section
	Symbols        []*Symbol

	closer io.Closer
}

type SectionHeader struct {
	Name                 string
	VirtualSize          uint32
	VirtualAddress       uint32
	Size                 uint32
	Offset               uint32
	PointerToRelocations uint32
	PointerToLineNumbers uint32
	NumberOfRelocations  uint16
	NumberOfLineNumbers  uint16
	Characteristics      uint32
}

type Section struct {
	SectionHeader

	// Embed ReaderAt for ReadAt method.
	// Do not embed SectionReader directly
	// to avoid having Read and Seek.
	// If a client wants Read and Seek it must use
	// Open() to avoid fighting over the seek offset
	// with other clients.
	io.ReaderAt
	sr *io.SectionReader
}

type Symbol struct {
	Name          string
	Value         uint32
	SectionNumber int16
	Type          uint16
	StorageClass  uint8
}

type ImportDirectory struct {
	OriginalFirstThunk uint32
	TimeDateStamp      uint32
	ForwarderChain     uint32
	Name               uint32
	FirstThunk         uint32

	dll string
}

// Data reads and returns the contents of the PE section.
func (s *Section) Data() ([]byte, error) {
	dat := make([]byte, s.sr.Size())
	n, err := s.sr.ReadAt(dat, 0)
	if n == len(dat) {
		err = nil
	}
	return dat[0:n], err
}

// Open returns a new ReadSeeker reading the PE section.
func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }

type FormatError struct {
	off int64
	msg string
	val interface{}
}

func (e *FormatError) Error() string {
	msg := e.msg
	if e.val != nil {
		msg += fmt.Sprintf(" '%v'", e.val)
	}
	msg += fmt.Sprintf(" in record at byte %#x", e.off)
	return msg
}

// Open opens the named file using os.Open and prepares it for use as a PE binary.
func Open(name string) (*File, error) {
	f, err := os.Open(name)
	if err != nil {
		return nil, err
	}
	ff, err := NewFile(f)
	if err != nil {
		f.Close()
		return nil, err
	}
	ff.closer = f
	return ff, nil
}

// Close closes the File.
// If the File was created using NewFile directly instead of Open,
// Close has no effect.
func (f *File) Close() error {
	var err error
	if f.closer != nil {
		err = f.closer.Close()
		f.closer = nil
	}
	return err
}

// NewFile creates a new File for accessing a PE binary in an underlying reader.
func NewFile(r io.ReaderAt) (*File, error) {
	f := new(File)
	sr := io.NewSectionReader(r, 0, 1<<63-1)

	var dosheader [96]byte
	if _, err := r.ReadAt(dosheader[0:], 0); err != nil {
		return nil, err
	}
	var base int64
	if dosheader[0] == 'M' && dosheader[1] == 'Z' {
		signoff := int64(binary.LittleEndian.Uint32(dosheader[0x3c:]))
		var sign [4]byte
		r.ReadAt(sign[:], signoff)
		if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) {
			return nil, errors.New("Invalid PE File Format.")
		}
		base = signoff + 4
	} else {
		base = int64(0)
	}
	sr.Seek(base, os.SEEK_SET)
	if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
		return nil, err
	}
	if f.FileHeader.Machine != IMAGE_FILE_MACHINE_UNKNOWN && f.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64 && f.FileHeader.Machine != IMAGE_FILE_MACHINE_I386 {
		return nil, errors.New("Invalid PE File Format.")
	}

	var ss []byte
	if f.FileHeader.NumberOfSymbols > 0 {
		// Get COFF string table, which is located at the end of the COFF symbol table.
		sr.Seek(int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols), os.SEEK_SET)
		var l uint32
		if err := binary.Read(sr, binary.LittleEndian, &l); err != nil {
			return nil, err
		}
		ss = make([]byte, l)
		if _, err := r.ReadAt(ss, int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols)); err != nil {
			return nil, err
		}

		// Process COFF symbol table.
		sr.Seek(int64(f.FileHeader.PointerToSymbolTable), os.SEEK_SET)
		aux := uint8(0)
		for i := 0; i < int(f.FileHeader.NumberOfSymbols); i++ {
			cs := new(COFFSymbol)
			if err := binary.Read(sr, binary.LittleEndian, cs); err != nil {
				return nil, err
			}
			if aux > 0 {
				aux--
				continue
			}
			var name string
			if cs.Name[0] == 0 && cs.Name[1] == 0 && cs.Name[2] == 0 && cs.Name[3] == 0 {
				si := int(binary.LittleEndian.Uint32(cs.Name[4:]))
				name, _ = getString(ss, si)
			} else {
				name = cstring(cs.Name[:])
			}
			aux = cs.NumberOfAuxSymbols
			s := &Symbol{
				Name:          name,
				Value:         cs.Value,
				SectionNumber: cs.SectionNumber,
				Type:          cs.Type,
				StorageClass:  cs.StorageClass,
			}
			f.Symbols = append(f.Symbols, s)
		}
	}

	// Read optional header.
	sr.Seek(base, os.SEEK_SET)
	if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
		return nil, err
	}
	var oh32 OptionalHeader32
	var oh64 OptionalHeader64
	switch uintptr(f.FileHeader.SizeOfOptionalHeader) {
	case unsafe.Sizeof(oh32):
		if err := binary.Read(sr, binary.LittleEndian, &oh32); err != nil {
			return nil, err
		}
		if oh32.Magic != 0x10b { // PE32
			return nil, fmt.Errorf("pe32 optional header has unexpected Magic of 0x%x", oh32.Magic)
		}
		f.OptionalHeader = &oh32
	case unsafe.Sizeof(oh64):
		if err := binary.Read(sr, binary.LittleEndian, &oh64); err != nil {
			return nil, err
		}
		if oh64.Magic != 0x20b { // PE32+
			return nil, fmt.Errorf("pe32+ optional header has unexpected Magic of 0x%x", oh64.Magic)
		}
		f.OptionalHeader = &oh64
	}

	// Process sections.
	f.Sections = make([]*Section, f.FileHeader.NumberOfSections)
	for i := 0; i < int(f.FileHeader.NumberOfSections); i++ {
		sh := new(SectionHeader32)
		if err := binary.Read(sr, binary.LittleEndian, sh); err != nil {
			return nil, err
		}
		var name string
		if sh.Name[0] == '\x2F' {
			si, _ := strconv.Atoi(cstring(sh.Name[1:]))
			name, _ = getString(ss, si)
		} else {
			name = cstring(sh.Name[0:])
		}
		s := new(Section)
		s.SectionHeader = SectionHeader{
			Name:                 name,
			VirtualSize:          sh.VirtualSize,
			VirtualAddress:       sh.VirtualAddress,
			Size:                 sh.SizeOfRawData,
			Offset:               sh.PointerToRawData,
			PointerToRelocations: sh.PointerToRelocations,
			PointerToLineNumbers: sh.PointerToLineNumbers,
			NumberOfRelocations:  sh.NumberOfRelocations,
			NumberOfLineNumbers:  sh.NumberOfLineNumbers,
			Characteristics:      sh.Characteristics,
		}
		s.sr = io.NewSectionReader(r, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size))
		s.ReaderAt = s.sr
		f.Sections[i] = s
	}
	return f, nil
}

func cstring(b []byte) string {
	var i int
	for i = 0; i < len(b) && b[i] != 0; i++ {
	}
	return string(b[0:i])
}

// getString extracts a string from symbol string table.
func getString(section []byte, start int) (string, bool) {
	if start < 0 || start >= len(section) {
		return "", false
	}

	for end := start; end < len(section); end++ {
		if section[end] == 0 {
			return string(section[start:end]), true
		}
	}
	return "", false
}

// Section returns the first section with the given name, or nil if no such
// section exists.
func (f *File) Section(name string) *Section {
	for _, s := range f.Sections {
		if s.Name == name {
			return s
		}
	}
	return nil
}

func (f *File) DWARF() (*dwarf.Data, error) {
	// There are many other DWARF sections, but these
	// are the required ones, and the debug/dwarf package
	// does not use the others, so don't bother loading them.
	var names = [...]string{"abbrev", "info", "str"}
	var dat [len(names)][]byte
	for i, name := range names {
		name = ".debug_" + name
		s := f.Section(name)
		if s == nil {
			continue
		}
		b, err := s.Data()
		if err != nil && uint32(len(b)) < s.Size {
			return nil, err
		}
		dat[i] = b
	}

	abbrev, info, str := dat[0], dat[1], dat[2]
	return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
}

// ImportedSymbols returns the names of all symbols
// referred to by the binary f that are expected to be
// satisfied by other libraries at dynamic load time.
// It does not return weak symbols.
func (f *File) ImportedSymbols() ([]string, error) {
	pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
	ds := f.Section(".idata")
	if ds == nil {
		// not dynamic, so no libraries
		return nil, nil
	}
	d, err := ds.Data()
	if err != nil {
		return nil, err
	}
	var ida []ImportDirectory
	for len(d) > 0 {
		var dt ImportDirectory
		dt.OriginalFirstThunk = binary.LittleEndian.Uint32(d[0:4])
		dt.Name = binary.LittleEndian.Uint32(d[12:16])
		dt.FirstThunk = binary.LittleEndian.Uint32(d[16:20])
		d = d[20:]
		if dt.OriginalFirstThunk == 0 {
			break
		}
		ida = append(ida, dt)
	}
	names, _ := ds.Data()
	var all []string
	for _, dt := range ida {
		dt.dll, _ = getString(names, int(dt.Name-ds.VirtualAddress))
		d, _ = ds.Data()
		// seek to OriginalFirstThunk
		d = d[dt.OriginalFirstThunk-ds.VirtualAddress:]
		for len(d) > 0 {
			if pe64 { // 64bit
				va := binary.LittleEndian.Uint64(d[0:8])
				d = d[8:]
				if va == 0 {
					break
				}
				if va&0x8000000000000000 > 0 { // is Ordinal
					// TODO add dynimport ordinal support.
				} else {
					fn, _ := getString(names, int(uint32(va)-ds.VirtualAddress+2))
					all = append(all, fn+":"+dt.dll)
				}
			} else { // 32bit
				va := binary.LittleEndian.Uint32(d[0:4])
				d = d[4:]
				if va == 0 {
					break
				}
				if va&0x80000000 > 0 { // is Ordinal
					// TODO add dynimport ordinal support.
					//ord := va&0x0000FFFF
				} else {
					fn, _ := getString(names, int(va-ds.VirtualAddress+2))
					all = append(all, fn+":"+dt.dll)
				}
			}
		}
	}

	return all, nil
}

// ImportedLibraries returns the names of all libraries
// referred to by the binary f that are expected to be
// linked with the binary at dynamic link time.
func (f *File) ImportedLibraries() ([]string, error) {
	// TODO
	// cgo -dynimport don't use this for windows PE, so just return.
	return nil, nil
}
<commit_msg>debug/pe: remove use of unsafe<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 pe implements access to PE (Microsoft Windows Portable Executable) files.
package pe

import (
	"debug/dwarf"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"os"
	"strconv"
)

// A File represents an open PE file.
type File struct {
	FileHeader
	OptionalHeader interface{} // of type *OptionalHeader32 or *OptionalHeader64
	Sections       []*Section
	Symbols        []*Symbol

	closer io.Closer
}

type SectionHeader struct {
	Name                 string
	VirtualSize          uint32
	VirtualAddress       uint32
	Size                 uint32
	Offset               uint32
	PointerToRelocations uint32
	PointerToLineNumbers uint32
	NumberOfRelocations  uint16
	NumberOfLineNumbers  uint16
	Characteristics      uint32
}

type Section struct {
	SectionHeader

	// Embed ReaderAt for ReadAt method.
	// Do not embed SectionReader directly
	// to avoid having Read and Seek.
	// If a client wants Read and Seek it must use
	// Open() to avoid fighting over the seek offset
	// with other clients.
	io.ReaderAt
	sr *io.SectionReader
}

type Symbol struct {
	Name          string
	Value         uint32
	SectionNumber int16
	Type          uint16
	StorageClass  uint8
}

type ImportDirectory struct {
	OriginalFirstThunk uint32
	TimeDateStamp      uint32
	ForwarderChain     uint32
	Name               uint32
	FirstThunk         uint32

	dll string
}

// Data reads and returns the contents of the PE section.
func (s *Section) Data() ([]byte, error) {
	dat := make([]byte, s.sr.Size())
	n, err := s.sr.ReadAt(dat, 0)
	if n == len(dat) {
		err = nil
	}
	return dat[0:n], err
}

// Open returns a new ReadSeeker reading the PE section.
func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }

type FormatError struct {
	off int64
	msg string
	val interface{}
}

func (e *FormatError) Error() string {
	msg := e.msg
	if e.val != nil {
		msg += fmt.Sprintf(" '%v'", e.val)
	}
	msg += fmt.Sprintf(" in record at byte %#x", e.off)
	return msg
}

// Open opens the named file using os.Open and prepares it for use as a PE binary.
func Open(name string) (*File, error) {
	f, err := os.Open(name)
	if err != nil {
		return nil, err
	}
	ff, err := NewFile(f)
	if err != nil {
		f.Close()
		return nil, err
	}
	ff.closer = f
	return ff, nil
}

// Close closes the File.
// If the File was created using NewFile directly instead of Open,
// Close has no effect.
func (f *File) Close() error {
	var err error
	if f.closer != nil {
		err = f.closer.Close()
		f.closer = nil
	}
	return err
}

var (
	sizeofOptionalHeader32 = uintptr(binary.Size(OptionalHeader32{}))
	sizeofOptionalHeader64 = uintptr(binary.Size(OptionalHeader64{}))
)

// NewFile creates a new File for accessing a PE binary in an underlying reader.
func NewFile(r io.ReaderAt) (*File, error) {
	f := new(File)
	sr := io.NewSectionReader(r, 0, 1<<63-1)

	var dosheader [96]byte
	if _, err := r.ReadAt(dosheader[0:], 0); err != nil {
		return nil, err
	}
	var base int64
	if dosheader[0] == 'M' && dosheader[1] == 'Z' {
		signoff := int64(binary.LittleEndian.Uint32(dosheader[0x3c:]))
		var sign [4]byte
		r.ReadAt(sign[:], signoff)
		if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) {
			return nil, errors.New("Invalid PE File Format.")
		}
		base = signoff + 4
	} else {
		base = int64(0)
	}
	sr.Seek(base, os.SEEK_SET)
	if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
		return nil, err
	}
	if f.FileHeader.Machine != IMAGE_FILE_MACHINE_UNKNOWN && f.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64 && f.FileHeader.Machine != IMAGE_FILE_MACHINE_I386 {
		return nil, errors.New("Invalid PE File Format.")
	}

	var ss []byte
	if f.FileHeader.NumberOfSymbols > 0 {
		// Get COFF string table, which is located at the end of the COFF symbol table.
		sr.Seek(int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols), os.SEEK_SET)
		var l uint32
		if err := binary.Read(sr, binary.LittleEndian, &l); err != nil {
			return nil, err
		}
		ss = make([]byte, l)
		if _, err := r.ReadAt(ss, int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols)); err != nil {
			return nil, err
		}

		// Process COFF symbol table.
		sr.Seek(int64(f.FileHeader.PointerToSymbolTable), os.SEEK_SET)
		aux := uint8(0)
		for i := 0; i < int(f.FileHeader.NumberOfSymbols); i++ {
			cs := new(COFFSymbol)
			if err := binary.Read(sr, binary.LittleEndian, cs); err != nil {
				return nil, err
			}
			if aux > 0 {
				aux--
				continue
			}
			var name string
			if cs.Name[0] == 0 && cs.Name[1] == 0 && cs.Name[2] == 0 && cs.Name[3] == 0 {
				si := int(binary.LittleEndian.Uint32(cs.Name[4:]))
				name, _ = getString(ss, si)
			} else {
				name = cstring(cs.Name[:])
			}
			aux = cs.NumberOfAuxSymbols
			s := &Symbol{
				Name:          name,
				Value:         cs.Value,
				SectionNumber: cs.SectionNumber,
				Type:          cs.Type,
				StorageClass:  cs.StorageClass,
			}
			f.Symbols = append(f.Symbols, s)
		}
	}

	// Read optional header.
	sr.Seek(base, os.SEEK_SET)
	if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
		return nil, err
	}
	var oh32 OptionalHeader32
	var oh64 OptionalHeader64
	switch uintptr(f.FileHeader.SizeOfOptionalHeader) {
	case sizeofOptionalHeader32:
		if err := binary.Read(sr, binary.LittleEndian, &oh32); err != nil {
			return nil, err
		}
		if oh32.Magic != 0x10b { // PE32
			return nil, fmt.Errorf("pe32 optional header has unexpected Magic of 0x%x", oh32.Magic)
		}
		f.OptionalHeader = &oh32
	case sizeofOptionalHeader64:
		if err := binary.Read(sr, binary.LittleEndian, &oh64); err != nil {
			return nil, err
		}
		if oh64.Magic != 0x20b { // PE32+
			return nil, fmt.Errorf("pe32+ optional header has unexpected Magic of 0x%x", oh64.Magic)
		}
		f.OptionalHeader = &oh64
	}

	// Process sections.
	f.Sections = make([]*Section, f.FileHeader.NumberOfSections)
	for i := 0; i < int(f.FileHeader.NumberOfSections); i++ {
		sh := new(SectionHeader32)
		if err := binary.Read(sr, binary.LittleEndian, sh); err != nil {
			return nil, err
		}
		var name string
		if sh.Name[0] == '\x2F' {
			si, _ := strconv.Atoi(cstring(sh.Name[1:]))
			name, _ = getString(ss, si)
		} else {
			name = cstring(sh.Name[0:])
		}
		s := new(Section)
		s.SectionHeader = SectionHeader{
			Name:                 name,
			VirtualSize:          sh.VirtualSize,
			VirtualAddress:       sh.VirtualAddress,
			Size:                 sh.SizeOfRawData,
			Offset:               sh.PointerToRawData,
			PointerToRelocations: sh.PointerToRelocations,
			PointerToLineNumbers: sh.PointerToLineNumbers,
			NumberOfRelocations:  sh.NumberOfRelocations,
			NumberOfLineNumbers:  sh.NumberOfLineNumbers,
			Characteristics:      sh.Characteristics,
		}
		s.sr = io.NewSectionReader(r, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size))
		s.ReaderAt = s.sr
		f.Sections[i] = s
	}
	return f, nil
}

func cstring(b []byte) string {
	var i int
	for i = 0; i < len(b) && b[i] != 0; i++ {
	}
	return string(b[0:i])
}

// getString extracts a string from symbol string table.
func getString(section []byte, start int) (string, bool) {
	if start < 0 || start >= len(section) {
		return "", false
	}

	for end := start; end < len(section); end++ {
		if section[end] == 0 {
			return string(section[start:end]), true
		}
	}
	return "", false
}

// Section returns the first section with the given name, or nil if no such
// section exists.
func (f *File) Section(name string) *Section {
	for _, s := range f.Sections {
		if s.Name == name {
			return s
		}
	}
	return nil
}

func (f *File) DWARF() (*dwarf.Data, error) {
	// There are many other DWARF sections, but these
	// are the required ones, and the debug/dwarf package
	// does not use the others, so don't bother loading them.
	var names = [...]string{"abbrev", "info", "str"}
	var dat [len(names)][]byte
	for i, name := range names {
		name = ".debug_" + name
		s := f.Section(name)
		if s == nil {
			continue
		}
		b, err := s.Data()
		if err != nil && uint32(len(b)) < s.Size {
			return nil, err
		}
		dat[i] = b
	}

	abbrev, info, str := dat[0], dat[1], dat[2]
	return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
}

// ImportedSymbols returns the names of all symbols
// referred to by the binary f that are expected to be
// satisfied by other libraries at dynamic load time.
// It does not return weak symbols.
func (f *File) ImportedSymbols() ([]string, error) {
	pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
	ds := f.Section(".idata")
	if ds == nil {
		// not dynamic, so no libraries
		return nil, nil
	}
	d, err := ds.Data()
	if err != nil {
		return nil, err
	}
	var ida []ImportDirectory
	for len(d) > 0 {
		var dt ImportDirectory
		dt.OriginalFirstThunk = binary.LittleEndian.Uint32(d[0:4])
		dt.Name = binary.LittleEndian.Uint32(d[12:16])
		dt.FirstThunk = binary.LittleEndian.Uint32(d[16:20])
		d = d[20:]
		if dt.OriginalFirstThunk == 0 {
			break
		}
		ida = append(ida, dt)
	}
	names, _ := ds.Data()
	var all []string
	for _, dt := range ida {
		dt.dll, _ = getString(names, int(dt.Name-ds.VirtualAddress))
		d, _ = ds.Data()
		// seek to OriginalFirstThunk
		d = d[dt.OriginalFirstThunk-ds.VirtualAddress:]
		for len(d) > 0 {
			if pe64 { // 64bit
				va := binary.LittleEndian.Uint64(d[0:8])
				d = d[8:]
				if va == 0 {
					break
				}
				if va&0x8000000000000000 > 0 { // is Ordinal
					// TODO add dynimport ordinal support.
				} else {
					fn, _ := getString(names, int(uint32(va)-ds.VirtualAddress+2))
					all = append(all, fn+":"+dt.dll)
				}
			} else { // 32bit
				va := binary.LittleEndian.Uint32(d[0:4])
				d = d[4:]
				if va == 0 {
					break
				}
				if va&0x80000000 > 0 { // is Ordinal
					// TODO add dynimport ordinal support.
					//ord := va&0x0000FFFF
				} else {
					fn, _ := getString(names, int(va-ds.VirtualAddress+2))
					all = append(all, fn+":"+dt.dll)
				}
			}
		}
	}

	return all, nil
}

// ImportedLibraries returns the names of all libraries
// referred to by the binary f that are expected to be
// linked with the binary at dynamic link time.
func (f *File) ImportedLibraries() ([]string, error) {
	// TODO
	// cgo -dynimport don't use this for windows PE, so just return.
	return nil, nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/slene/iploc"
)

type Result struct {
	NameServer        string
	NameServerCountry string
	Ip                string
	IpCountry         string
}

func collect(out chan Result, server NameServer, domain string) {
	ip, err := Query(&server, domain)
	var r Result
	r.NameServer = server.Addr()
	r.NameServerCountry = iploc.COUNTRIES_ZH[server.CountryID]
	if err != nil {
		out <- r
		return
	}

	r.DomainIp = ip.String()
	info, err := iploc.GetIpInfo(ip.String())
	if err == nil {
		r.DomainCountry = info.Country
	}
	out <- r
	fmt.Printf("%#v\n", r)
}

func main() {
	dns := flag.String("ns", "", "name servers")
	_domain := flag.String("domain", "", "domain")
	output := flag.String("o", "", "output json file")

	flag.Parse()
	domain := *_domain
	if *dns == "" || domain == "" {
		fmt.Println("invalid args")
		flag.PrintDefaults()
		os.Exit(1)
	}

	ns, err := loadNameServers(*dns)
	if err != nil {
		fmt.Println(err)
		flag.PrintDefaults()
		os.Exit(1)
	}

	if !strings.HasSuffix(domain, ".") {
		domain += "."
	}

	// replace iplocFilePath to your iploc.dat path
	iplocFilePath, _ := filepath.Abs("bin/iploc.dat")

	// simple set a true param can preload all ipinfo
	// need allocate more memory > 30M
	// and speed can grow up about 40 percent than not preload
	iploc.IpLocInit(iplocFilePath, true)
	var rets []Result
	chans := make(chan Result, len(ns))
	for _, v := range ns {
		go collect(chans, v, domain)
	}

	for i := 0; i < len(ns); i++ {
		done := <-chans
		if done.DomainIp != "" {
			rets = append(rets, done)
		}
	}
	if *output != "" {
		data, err := json.MarshalIndent(rets, "", "")
		if err != nil {
			fmt.Println(err)
			return
		}
		err = ioutil.WriteFile(*output, data, 0666)
		if err != nil {
			fmt.Println(err)
		}
	}
}
<commit_msg>fixed compile<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/slene/iploc"
)

type Result struct {
	NameServer        string
	NameServerCountry string
	Ip                string
	IpCountry         string
}

func collect(out chan Result, server NameServer, domain string) {
	ip, err := Query(&server, domain)
	var r Result
	r.NameServer = server.Addr()
	r.NameServerCountry = iploc.COUNTRIES_ZH[server.CountryID]
	if err != nil {
		out <- r
		return
	}

	r.Ip = ip.String()
	info, err := iploc.GetIpInfo(ip.String())
	if err == nil {
		r.IpCountry = info.Country
	}
	out <- r
	fmt.Printf("%#v\n", r)
}

func main() {
	dns := flag.String("ns", "", "name servers")
	_domain := flag.String("domain", "", "domain")
	output := flag.String("o", "", "output json file")

	flag.Parse()
	domain := *_domain
	if *dns == "" || domain == "" {
		fmt.Println("invalid args")
		flag.PrintDefaults()
		os.Exit(1)
	}

	ns, err := loadNameServers(*dns)
	if err != nil {
		fmt.Println(err)
		flag.PrintDefaults()
		os.Exit(1)
	}

	if !strings.HasSuffix(domain, ".") {
		domain += "."
	}

	// replace iplocFilePath to your iploc.dat path
	iplocFilePath, _ := filepath.Abs("bin/iploc.dat")

	// simple set a true param can preload all ipinfo
	// need allocate more memory > 30M
	// and speed can grow up about 40 percent than not preload
	iploc.IpLocInit(iplocFilePath, true)
	var rets []Result
	chans := make(chan Result, len(ns))
	for _, v := range ns {
		go collect(chans, v, domain)
	}

	for i := 0; i < len(ns); i++ {
		done := <-chans
		if done.Ip != "" {
			rets = append(rets, done)
		}
	}
	if *output != "" {
		data, err := json.MarshalIndent(rets, "", "")
		if err != nil {
			fmt.Println(err)
			return
		}
		err = ioutil.WriteFile(*output, data, 0666)
		if err != nil {
			fmt.Println(err)
		}
	}
}
<|endoftext|>


<commit_before>package mesos

import (
	"fmt"
	"log"

	"github.com/CiscoCloud/mesos-consul/registry"
)

type registryState struct {
	services	map[string]bool
	followers	map[string]bool
	masters		map[string]MesosHost
}

var currentState = registryState{
	services:	make(map[string]bool),
	followers:	make(map[string]bool),
	masters:	make(map[string]MesosHost),
}

func (m *Mesos) RegisterHosts(sj StateJSON) {
	log.Print("Running RegisterHosts")

	// Register followers
	for _, f := range sj.Followers {
		id := fmt.Sprintf("%s:%s", f.Id, f.Hostname)
		if _, ok := currentState.followers[id]; ok {
			log.Printf("Id found: '%s': Not registering", id)
			currentState.followers[id] = true
		} else {
			currentState.followers[id] = true

			s := new(registry.Service)

			host, port := parsePID(f.Pid)

			s.ID	= id
			s.Name	= "mesos"
			s.Port	= toPort(port)
			s.IP	= toIP(host)
			s.Tags	= []string{
				"follower",
				}

			c := new(registry.ServiceCheck)
			c.HTTP = fmt.Sprintf("https://%s:%s/slave(1)/health", s.IP, s.Port)
			c.Interval = "10s"
			s.Check = c

			log.Print("Registering: ", id)

			err := m.registry.Register(s)
			if err != nil {
				log.Print(err)
			}
		}
	}

	// Register masters
	mas := m.getMasters()
	for _, ma := range mas {
		id := fmt.Sprintf("%s:%s", ma.host, ma.port)
		if master, ok := currentState.masters[id]; ok {
			// Master has been found. Only update if the leader status has changed
			if ma.isLeader ==  master.isLeader {
				master.isRegistered = true
				log.Printf("Master state unchanged, not registering: '%s'", id)
				continue
			}
		}

		ma.isRegistered = true
		currentState.masters[id] = ma

		s := new(registry.Service)
		s.ID	= fmt.Sprintf("mesos:%s:%s", ma.host, ma.port)
		s.Name	= "mesos"
		s.Port	= toPort(ma.port)
		s.IP	= toIP(ma.host)
		if ma.isLeader {
			s.Tags	= []string{
				"master",
				}
		} else {
			s.Tags	= []string{
				"master",
				"leader",
				}
		}

		c := new(registry.ServiceCheck)
		c.HTTP = fmt.Sprintf("https://%s:%s/master/health", s.IP, s.Port)
		c.Interval = "10s"
		s.Check = c

		log.Print("Registering: ", s.ID)
		err := m.registry.Register(s)
		if err != nil {
			log.Print(err)
		}
	}
}

func (m *Mesos) register(s *registry.Service) {
	if _, ok := currentState.services[s.ID]; ok {
		log.Printf("Service found. Not registering: %s", s.ID)
		currentState.services[s.ID] = true
		return
	}

	log.Print("Registering ", s.ID)

	currentState.services[s.ID] = true
	err := m.registry.Register(s)
	if err != nil {
		log.Print(err)
	}
}

// deregister items that have gone away
//
func (m *Mesos) deregister() {
	// Services
	for s, b := range currentState.services {
		if !b {
			log.Print("Deregistering ", s)
			m.registry.Deregister(&registry.Service{
				ID:		s,
				})

			delete(currentState.services, s)
		} else {
			currentState.services[s] = false
		}
	}

	// Followers
	for id, isRegistered := range currentState.followers {
		if !isRegistered {
			log.Print("Deregistering ", id)
			m.registry.Deregister(&registry.Service{
				ID:		id,
				})
			delete(currentState.followers, id)
		} else {
			currentState.followers[id] = false
		}
	}

	// Masters
	for id, master := range currentState.masters {
		if !master.isRegistered {
			log.Print("Deregistering ", id)
			m.registry.Deregister(&registry.Service{
				ID:		id,
				})
			delete(currentState.masters, id)
		} else {
			master.isRegistered = false
		}
	}
}
<commit_msg>Use proper type in mesos check string<commit_after>package mesos

import (
	"fmt"
	"log"

	"github.com/CiscoCloud/mesos-consul/registry"
)

type registryState struct {
	services	map[string]bool
	followers	map[string]bool
	masters		map[string]MesosHost
}

var currentState = registryState{
	services:	make(map[string]bool),
	followers:	make(map[string]bool),
	masters:	make(map[string]MesosHost),
}

func (m *Mesos) RegisterHosts(sj StateJSON) {
	log.Print("Running RegisterHosts")

	// Register followers
	for _, f := range sj.Followers {
		id := fmt.Sprintf("%s:%s", f.Id, f.Hostname)
		if _, ok := currentState.followers[id]; ok {
			log.Printf("Id found: '%s': Not registering", id)
			currentState.followers[id] = true
		} else {
			currentState.followers[id] = true

			s := new(registry.Service)

			host, port := parsePID(f.Pid)

			s.ID	= id
			s.Name	= "mesos"
			s.Port	= toPort(port)
			s.IP	= toIP(host)
			s.Tags	= []string{
				"follower",
				}

			c := new(registry.ServiceCheck)
			c.HTTP = fmt.Sprintf("https://%s:%d/slave(1)/health", s.IP, s.Port)
			c.Interval = "10s"
			s.Check = c

			log.Print("Registering: ", id)

			err := m.registry.Register(s)
			if err != nil {
				log.Print(err)
			}
		}
	}

	// Register masters
	mas := m.getMasters()
	for _, ma := range mas {
		id := fmt.Sprintf("%s:%s", ma.host, ma.port)
		if master, ok := currentState.masters[id]; ok {
			// Master has been found. Only update if the leader status has changed
			if ma.isLeader ==  master.isLeader {
				master.isRegistered = true
				log.Printf("Master state unchanged, not registering: '%s'", id)
				continue
			}
		}

		ma.isRegistered = true
		currentState.masters[id] = ma

		s := new(registry.Service)
		s.ID	= fmt.Sprintf("mesos:%s:%s", ma.host, ma.port)
		s.Name	= "mesos"
		s.Port	= toPort(ma.port)
		s.IP	= toIP(ma.host)
		if ma.isLeader {
			s.Tags	= []string{
				"master",
				}
		} else {
			s.Tags	= []string{
				"master",
				"leader",
				}
		}

		c := new(registry.ServiceCheck)
		c.HTTP = fmt.Sprintf("https://%s:%d/master/health", s.IP, s.Port)
		c.Interval = "10s"
		s.Check = c

		log.Print("Registering: ", s.ID)
		err := m.registry.Register(s)
		if err != nil {
			log.Print(err)
		}
	}
}

func (m *Mesos) register(s *registry.Service) {
	if _, ok := currentState.services[s.ID]; ok {
		log.Printf("Service found. Not registering: %s", s.ID)
		currentState.services[s.ID] = true
		return
	}

	log.Print("Registering ", s.ID)

	currentState.services[s.ID] = true
	err := m.registry.Register(s)
	if err != nil {
		log.Print(err)
	}
}

// deregister items that have gone away
//
func (m *Mesos) deregister() {
	// Services
	for s, b := range currentState.services {
		if !b {
			log.Print("Deregistering ", s)
			m.registry.Deregister(&registry.Service{
				ID:		s,
				})

			delete(currentState.services, s)
		} else {
			currentState.services[s] = false
		}
	}

	// Followers
	for id, isRegistered := range currentState.followers {
		if !isRegistered {
			log.Print("Deregistering ", id)
			m.registry.Deregister(&registry.Service{
				ID:		id,
				})
			delete(currentState.followers, id)
		} else {
			currentState.followers[id] = false
		}
	}

	// Masters
	for id, master := range currentState.masters {
		if !master.isRegistered {
			log.Print("Deregistering ", id)
			m.registry.Deregister(&registry.Service{
				ID:		id,
				})
			delete(currentState.masters, id)
		} else {
			master.isRegistered = false
		}
	}
}
<|endoftext|>


<commit_before>package messages

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"time"

	"github.com/aarbt/bitcoin-wallet/utils"
)

type GetBlocks struct {
	Version  int32
	Locators [][]byte
	HashStop []byte
}

func (g *GetBlocks) Serialize(w io.Writer) error {
	err := binary.Write(w, binary.LittleEndian, g.Version)
	if err != nil {
		return fmt.Errorf("Failed to write version field: %v", err)
	}
	err = WriteCompactUint(uint(len(g.Locators)), w)
	if err != nil {
		return fmt.Errorf("Failed to write hash count field: %v", err)
	}
	for i, l := range g.Locators {
		_, err := w.Write(l)
		if err != nil {
			return fmt.Errorf("Failed to write locator %d: %v", i, err)
		}
	}
	_, err = w.Write(g.HashStop)
	if err != nil {
		return fmt.Errorf("Failed to write hash stop field: %v", err)
	}
	return nil
}

type BlockHeader struct {
	Version    int32  // 4 bytes
	PrevBlock  []byte // 32 bytes
	MerkleRoot []byte // 32 bytes
	Timestamp  uint32
	Bits       uint32
	Nonce      uint32

	hash []byte // not in protocol message.
}

func (h *BlockHeader) Serialize(w io.Writer) error {
	err := binary.Write(w, binary.LittleEndian, h.Version)
	if err != nil {
		return fmt.Errorf("Failed to write version field: %v", err)
	}
	_, err = w.Write(h.PrevBlock)
	if err != nil {
		return fmt.Errorf("Failed to write prev block: %v", err)
	}
	_, err = w.Write(h.MerkleRoot)
	if err != nil {
		return fmt.Errorf("Failed to write merkle root: %v", err)
	}
	err = binary.Write(w, binary.LittleEndian, h.Timestamp)
	if err != nil {
		return fmt.Errorf("Failed to write timestamp: %v", err)
	}
	err = binary.Write(w, binary.LittleEndian, h.Bits)
	if err != nil {
		return fmt.Errorf("Failed to write bits: %v", err)
	}
	err = binary.Write(w, binary.LittleEndian, h.Nonce)
	if err != nil {
		return fmt.Errorf("Failed to write nonce: %v", err)
	}
	return nil
}

func (h *BlockHeader) Hash() []byte {
	if h.hash == nil {
		var b bytes.Buffer
		h.Serialize(&b)
		h.hash = utils.DoubleHash(b.Bytes())
	}
	return h.hash
}

type ExtendedHeader struct {
	BlockHeader
	Count        uint
	data         []byte    // not in protocol message.
	Height       uint      // not in protocol message.
	FetchedBlock time.Time // not in protocol message.
}

func (h *ExtendedHeader) Data() []byte {
	// TODO Serialize header if data is empty.
	return h.data
}

func (h *ExtendedHeader) Hash() []byte {
	return h.BlockHeader.Hash()
}

type Headers []*ExtendedHeader

func ParseHeaders(data []byte) (Headers, error) {
	b := bytes.NewBuffer(data)
	count, err := ParseCompactUint(b)
	if err != nil {
		return nil, fmt.Errorf("Could not read header count field: %v", err)
	}
	vector := make([]*ExtendedHeader, count)
	for i, _ := range vector {
		h, err := ParseExtendedHeader(b)
		if err != nil {
			return nil, fmt.Errorf("Could not parse tx number %d: %v", i, err)
		}
		vector[i] = h
	}
	if b.Len() != 0 {
		return nil, fmt.Errorf("Excess data: %x", b.Bytes())
	}
	return Headers(vector), nil
}

type Block struct {
	BlockHeader  // 80 bytes
	Transactions []*Transaction
	Hash         []byte // 32 bytes
}

func (b *Block) String() string {
	str := fmt.Sprintf("%x, version %d\n", utils.ReverseBytes(b.Hash), b.Version)
	str += fmt.Sprintf("PrevBlock: %x\n", b.PrevBlock)
	str += fmt.Sprintf("MerkleRoot: %x\n", b.MerkleRoot)
	str += fmt.Sprintf("Timestamp: %s (%d)\n",
		time.Unix(int64(b.Timestamp), 0), b.Timestamp)
	str += fmt.Sprintf("Bits: 0x%x\n", b.Bits)
	str += fmt.Sprintf("Transactions (%d):\n", len(b.Transactions))
	for i, tx := range b.Transactions {
		str += fmt.Sprintf("TX %d: %s\n", i, tx)
	}
	return str
}

func ParseBlock(data []byte) (*Block, error) {
	var err error
	block := Block{
		Hash: utils.DoubleHash(data[0:80]),
	}
	b := bytes.NewBuffer(data)
	block.BlockHeader, err = parseBlockHeader(b)
	if err != nil {
		return nil, err
	}
	block.Transactions, err = parseTransactions(b)
	if err != nil {
		return nil, fmt.Errorf("Could not parse transactions: %v", err)
	}
	if b.Len() != 0 {
		return nil, fmt.Errorf("Excess data: %x", b.Bytes())
	}
	return &block, nil
}

type MerkleBlock struct {
	BlockHeader // 80 bytes
	TotalTXs    uint32
	Hashes      [][]byte
	Flags       []byte
}

func ParseMerkleBlock(data []byte) (*MerkleBlock, error) {
	var err error
	block := MerkleBlock{}
	b := bytes.NewBuffer(data)
	block.BlockHeader, err = parseBlockHeader(b)
	if err != nil {
		return nil, err
	}
	err = binary.Read(b, binary.LittleEndian, &block.TotalTXs)
	if err != nil {
		return nil, fmt.Errorf("Could not parse transactions: %v", err)
	}
	block.Hashes, err = parseHashes(b)
	if err != nil {
		return nil, err
	}
	block.Flags, err = parseFlags(b)
	if err != nil {
		return nil, err
	}
	if b.Len() != 0 {
		return nil, fmt.Errorf("Excess data: %x", b.Bytes())
	}
	return &block, nil
}

func parseHashes(b io.Reader) ([][]byte, error) {
	count, err := ParseCompactUint(b)
	if err != nil {
		return nil, fmt.Errorf("Could not read hash count field: %v", err)
	}
	vector := make([][]byte, count)
	for i, _ := range vector {
		hash, err := ParseBytes(b, 32)
		if err != nil {
			return nil, fmt.Errorf("Could not parse hash %d: %v", i, err)
		}
		vector[i] = hash
	}
	return vector, nil
}

func parseFlags(b io.Reader) ([]byte, error) {
	count, err := ParseCompactUint(b)
	if err != nil {
		return nil, fmt.Errorf("Could not read flag count field: %v", err)
	}
	return ParseBytes(b, int(count))
}

func parseBlockHeader(b io.Reader) (BlockHeader, error) {
	header := BlockHeader{}
	var err error
	err = binary.Read(b, binary.LittleEndian, &header.Version)
	if err != nil {
		return header, fmt.Errorf("Could not read version field: %v", err)
	}
	header.PrevBlock, err = ParseBytes(b, 32)
	if err != nil {
		return header, fmt.Errorf("Could not read PrevBlock field: %v", err)
	}
	header.MerkleRoot, err = ParseBytes(b, 32)
	if err != nil {
		return header, fmt.Errorf("Could not read MerkleRoot field: %v", err)
	}
	err = binary.Read(b, binary.LittleEndian, &header.Timestamp)
	if err != nil {
		return header, fmt.Errorf("Could not read timestamp field: %v", err)
	}
	err = binary.Read(b, binary.LittleEndian, &header.Bits)
	if err != nil {
		return header, fmt.Errorf("Could not read bits field: %v", err)
	}
	err = binary.Read(b, binary.LittleEndian, &header.Nonce)
	if err != nil {
		return header, fmt.Errorf("Could not read bits field: %v", err)
	}
	return header, nil
}

func parseTransactions(b io.Reader) ([]*Transaction, error) {
	count, err := ParseCompactUint(b)
	if err != nil {
		return nil, fmt.Errorf("Could not read transaction count field: %v", err)
	}
	vector := make([]*Transaction, count)
	for i, _ := range vector {
		t, err := ParseTransactionFromStream(b)
		if err != nil {
			return nil, fmt.Errorf("Could not parse tx number %d: %v", i, err)
		}
		vector[i] = t
	}
	return vector, nil
}

func ParseExtendedHeader(input io.Reader) (*ExtendedHeader, error) {
	var err error
	var data bytes.Buffer
	b := io.TeeReader(input, &data)

	header := ExtendedHeader{}
	header.BlockHeader, err = parseBlockHeader(b)
	if err != nil {
		return nil, err
	}
	header.Count, err = ParseCompactUint(b)
	if err != nil {
		return nil, err
	}
	header.data = data.Bytes()
	return &header, nil
}
<commit_msg>Move Height variable to BlockHeader to apply it to merkleblocks as well.<commit_after>package messages

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"time"

	"github.com/aarbt/bitcoin-wallet/utils"
)

type GetBlocks struct {
	Version  int32
	Locators [][]byte
	HashStop []byte
}

func (g *GetBlocks) Serialize(w io.Writer) error {
	err := binary.Write(w, binary.LittleEndian, g.Version)
	if err != nil {
		return fmt.Errorf("Failed to write version field: %v", err)
	}
	err = WriteCompactUint(uint(len(g.Locators)), w)
	if err != nil {
		return fmt.Errorf("Failed to write hash count field: %v", err)
	}
	for i, l := range g.Locators {
		_, err := w.Write(l)
		if err != nil {
			return fmt.Errorf("Failed to write locator %d: %v", i, err)
		}
	}
	_, err = w.Write(g.HashStop)
	if err != nil {
		return fmt.Errorf("Failed to write hash stop field: %v", err)
	}
	return nil
}

type BlockHeader struct {
	Version    int32  // 4 bytes
	PrevBlock  []byte // 32 bytes
	MerkleRoot []byte // 32 bytes
	Timestamp  uint32
	Bits       uint32
	Nonce      uint32

	hash   []byte // not in protocol message.
	Height int    // not in protocol message.
}

func (h *BlockHeader) Serialize(w io.Writer) error {
	err := binary.Write(w, binary.LittleEndian, h.Version)
	if err != nil {
		return fmt.Errorf("Failed to write version field: %v", err)
	}
	_, err = w.Write(h.PrevBlock)
	if err != nil {
		return fmt.Errorf("Failed to write prev block: %v", err)
	}
	_, err = w.Write(h.MerkleRoot)
	if err != nil {
		return fmt.Errorf("Failed to write merkle root: %v", err)
	}
	err = binary.Write(w, binary.LittleEndian, h.Timestamp)
	if err != nil {
		return fmt.Errorf("Failed to write timestamp: %v", err)
	}
	err = binary.Write(w, binary.LittleEndian, h.Bits)
	if err != nil {
		return fmt.Errorf("Failed to write bits: %v", err)
	}
	err = binary.Write(w, binary.LittleEndian, h.Nonce)
	if err != nil {
		return fmt.Errorf("Failed to write nonce: %v", err)
	}
	return nil
}

func (h *BlockHeader) Hash() []byte {
	if h.hash == nil {
		var b bytes.Buffer
		h.Serialize(&b)
		h.hash = utils.DoubleHash(b.Bytes())
	}
	return h.hash
}

type ExtendedHeader struct {
	BlockHeader
	Count uint

	data []byte // not in protocol message.
}

func (h *ExtendedHeader) Data() []byte {
	// TODO Serialize header if data is empty.
	return h.data
}

func (h *ExtendedHeader) Hash() []byte {
	return h.BlockHeader.Hash()
}

type Headers []*ExtendedHeader

func ParseHeaders(data []byte) (Headers, error) {
	b := bytes.NewBuffer(data)
	count, err := ParseCompactUint(b)
	if err != nil {
		return nil, fmt.Errorf("Could not read header count field: %v", err)
	}
	vector := make([]*ExtendedHeader, count)
	for i, _ := range vector {
		h, err := ParseExtendedHeader(b)
		if err != nil {
			return nil, fmt.Errorf("Could not parse tx number %d: %v", i, err)
		}
		vector[i] = h
	}
	if b.Len() != 0 {
		return nil, fmt.Errorf("Excess data: %x", b.Bytes())
	}
	return Headers(vector), nil
}

type Block struct {
	BlockHeader  // 80 bytes
	Transactions []*Transaction
	Hash         []byte // 32 bytes
}

func (b *Block) String() string {
	str := fmt.Sprintf("%x, version %d\n", utils.ReverseBytes(b.Hash), b.Version)
	str += fmt.Sprintf("PrevBlock: %x\n", b.PrevBlock)
	str += fmt.Sprintf("MerkleRoot: %x\n", b.MerkleRoot)
	str += fmt.Sprintf("Timestamp: %s (%d)\n",
		time.Unix(int64(b.Timestamp), 0), b.Timestamp)
	str += fmt.Sprintf("Bits: 0x%x\n", b.Bits)
	str += fmt.Sprintf("Transactions (%d):\n", len(b.Transactions))
	for i, tx := range b.Transactions {
		str += fmt.Sprintf("TX %d: %s\n", i, tx)
	}
	return str
}

func ParseBlock(data []byte) (*Block, error) {
	var err error
	block := Block{
		Hash: utils.DoubleHash(data[0:80]),
	}
	b := bytes.NewBuffer(data)
	block.BlockHeader, err = parseBlockHeader(b)
	if err != nil {
		return nil, err
	}
	block.Transactions, err = parseTransactions(b)
	if err != nil {
		return nil, fmt.Errorf("Could not parse transactions: %v", err)
	}
	if b.Len() != 0 {
		return nil, fmt.Errorf("Excess data: %x", b.Bytes())
	}
	return &block, nil
}

type MerkleBlock struct {
	BlockHeader // 80 bytes
	TotalTXs    uint32
	Hashes      [][]byte
	Flags       []byte
}

func ParseMerkleBlock(data []byte) (*MerkleBlock, error) {
	var err error
	block := MerkleBlock{}
	b := bytes.NewBuffer(data)
	block.BlockHeader, err = parseBlockHeader(b)
	if err != nil {
		return nil, err
	}
	err = binary.Read(b, binary.LittleEndian, &block.TotalTXs)
	if err != nil {
		return nil, fmt.Errorf("Could not parse transactions: %v", err)
	}
	block.Hashes, err = parseHashes(b)
	if err != nil {
		return nil, err
	}
	block.Flags, err = parseFlags(b)
	if err != nil {
		return nil, err
	}
	if b.Len() != 0 {
		return nil, fmt.Errorf("Excess data: %x", b.Bytes())
	}
	return &block, nil
}

func parseHashes(b io.Reader) ([][]byte, error) {
	count, err := ParseCompactUint(b)
	if err != nil {
		return nil, fmt.Errorf("Could not read hash count field: %v", err)
	}
	vector := make([][]byte, count)
	for i, _ := range vector {
		hash, err := ParseBytes(b, 32)
		if err != nil {
			return nil, fmt.Errorf("Could not parse hash %d: %v", i, err)
		}
		vector[i] = hash
	}
	return vector, nil
}

func parseFlags(b io.Reader) ([]byte, error) {
	count, err := ParseCompactUint(b)
	if err != nil {
		return nil, fmt.Errorf("Could not read flag count field: %v", err)
	}
	return ParseBytes(b, int(count))
}

func parseBlockHeader(b io.Reader) (BlockHeader, error) {
	header := BlockHeader{}
	var err error
	err = binary.Read(b, binary.LittleEndian, &header.Version)
	if err != nil {
		return header, fmt.Errorf("Could not read version field: %v", err)
	}
	header.PrevBlock, err = ParseBytes(b, 32)
	if err != nil {
		return header, fmt.Errorf("Could not read PrevBlock field: %v", err)
	}
	header.MerkleRoot, err = ParseBytes(b, 32)
	if err != nil {
		return header, fmt.Errorf("Could not read MerkleRoot field: %v", err)
	}
	err = binary.Read(b, binary.LittleEndian, &header.Timestamp)
	if err != nil {
		return header, fmt.Errorf("Could not read timestamp field: %v", err)
	}
	err = binary.Read(b, binary.LittleEndian, &header.Bits)
	if err != nil {
		return header, fmt.Errorf("Could not read bits field: %v", err)
	}
	err = binary.Read(b, binary.LittleEndian, &header.Nonce)
	if err != nil {
		return header, fmt.Errorf("Could not read bits field: %v", err)
	}
	return header, nil
}

func parseTransactions(b io.Reader) ([]*Transaction, error) {
	count, err := ParseCompactUint(b)
	if err != nil {
		return nil, fmt.Errorf("Could not read transaction count field: %v", err)
	}
	vector := make([]*Transaction, count)
	for i, _ := range vector {
		t, err := ParseTransactionFromStream(b)
		if err != nil {
			return nil, fmt.Errorf("Could not parse tx number %d: %v", i, err)
		}
		vector[i] = t
	}
	return vector, nil
}

func ParseExtendedHeader(input io.Reader) (*ExtendedHeader, error) {
	var err error
	var data bytes.Buffer
	b := io.TeeReader(input, &data)

	header := ExtendedHeader{}
	header.BlockHeader, err = parseBlockHeader(b)
	if err != nil {
		return nil, err
	}
	header.Count, err = ParseCompactUint(b)
	if err != nil {
		return nil, err
	}
	header.data = data.Bytes()
	return &header, nil
}
<|endoftext|>


<commit_before>package cache

import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"io"
	"net/http"
	"net/http/httptest"
	"os"
	"sync"
	"testing"
)

func TestDownloadFile(t *testing.T) {
	cacheDir := createTmpDir(t)
	defer os.RemoveAll(cacheDir)

	hash := createRandomFile(cacheDir, 1024)

	e := NewEnsureSpacer(1, 1)
	h := NewHTTPCache(cacheDir, 1024, e)

	req, err := http.NewRequest("GET", "/cas/"+hash, nil)
	if err != nil {
		t.Error(err)
	}
	rr := httptest.NewRecorder()
	handler := http.HandlerFunc(h.CacheHandler)
	handler.ServeHTTP(rr, req)

	if status := rr.Code; status != http.StatusOK {
		t.Error("Handler returned wrong status code",
			"expected", http.StatusOK,
			"got", status,
		)
	}

	rsp := rr.Result()
	if contentLen := rsp.ContentLength; contentLen != 1024 {
		t.Error("Handler returned file with wrong content length",
			"expected", 1024,
			"got", contentLen)
	}

	hasher := sha256.New()
	io.Copy(hasher, rsp.Body)
	if actualHash := hex.EncodeToString(hasher.Sum(nil)); actualHash != hash {
		t.Error("Received the wrong content.",
			"expected hash", hash,
			"actualHash", actualHash,
		)
	}
}

func TestUploadFilesConcurrently(t *testing.T) {
	cacheDir := createTmpDir(t)
	defer os.RemoveAll(cacheDir)

	const NumUploads = 1000

	var requests [NumUploads]*http.Request
	for i := 0; i < NumUploads; i++ {
		data, hash := randomDataAndHash(1024)
		r, err := http.NewRequest("PUT", "/cas/"+hash, bytes.NewReader(data))
		if err != nil {
			t.Error(err)
		}
		requests[i] = r
	}

	e := NewEnsureSpacer(0.8, 0.5)
	h := NewHTTPCache(cacheDir, 1000*1024, e)
	handler := http.HandlerFunc(h.CacheHandler)

	var wg sync.WaitGroup
	wg.Add(len(requests))
	for _, request := range requests {
		go func(request *http.Request) {
			defer wg.Done()
			rr := httptest.NewRecorder()
			handler.ServeHTTP(rr, request)

			if status := rr.Code; status != http.StatusOK {
				t.Error("Handler returned wrong status code",
					"expected", http.StatusOK,
					"got", status,
				)
			}
		}(request)
	}

	wg.Wait()

	f, err := os.Open(cacheDir)
	defer f.Close()
	if err != nil {
		t.Error(err)
	}
	files, err := f.Readdir(-1)
	if err != nil {
		t.Error(err)
	}
	var totalSize int64
	for _, fileinfo := range files {
		size := fileinfo.Size()
		if size != 1024 {
			t.Error("Expected all files to be 1024 bytes.", "Got", size)
		}
		totalSize += fileinfo.Size()
	}

	// Test that purging worked and kept cache size in check.
	if upperBound := int64(NumUploads) * 1024 * 1024; totalSize > upperBound {
		t.Error("Cache size too big. Expected at most", upperBound, "got",
			totalSize)
	}
}
<commit_msg>http: test concurrent upload of same file<commit_after>package cache

import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"io"
	"net/http"
	"net/http/httptest"
	"os"
	"sync"
	"testing"
)

func TestDownloadFile(t *testing.T) {
	cacheDir := createTmpDir(t)
	defer os.RemoveAll(cacheDir)

	hash := createRandomFile(cacheDir, 1024)

	e := NewEnsureSpacer(1, 1)
	h := NewHTTPCache(cacheDir, 1024, e)

	req, err := http.NewRequest("GET", "/cas/"+hash, nil)
	if err != nil {
		t.Error(err)
	}
	rr := httptest.NewRecorder()
	handler := http.HandlerFunc(h.CacheHandler)
	handler.ServeHTTP(rr, req)

	if status := rr.Code; status != http.StatusOK {
		t.Error("Handler returned wrong status code",
			"expected", http.StatusOK,
			"got", status,
		)
	}

	rsp := rr.Result()
	if contentLen := rsp.ContentLength; contentLen != 1024 {
		t.Error("Handler returned file with wrong content length",
			"expected", 1024,
			"got", contentLen)
	}

	hasher := sha256.New()
	io.Copy(hasher, rsp.Body)
	if actualHash := hex.EncodeToString(hasher.Sum(nil)); actualHash != hash {
		t.Error("Received the wrong content.",
			"expected hash", hash,
			"actualHash", actualHash,
		)
	}
}

func TestUploadFilesConcurrently(t *testing.T) {
	cacheDir := createTmpDir(t)
	defer os.RemoveAll(cacheDir)

	const NumUploads = 1000

	var requests [NumUploads]*http.Request
	for i := 0; i < NumUploads; i++ {
		data, hash := randomDataAndHash(1024)
		r, err := http.NewRequest("PUT", "/cas/"+hash, bytes.NewReader(data))
		if err != nil {
			t.Error(err)
		}
		requests[i] = r
	}

	e := NewEnsureSpacer(0.8, 0.5)
	h := NewHTTPCache(cacheDir, 1000*1024, e)
	handler := http.HandlerFunc(h.CacheHandler)

	var wg sync.WaitGroup
	wg.Add(len(requests))
	for _, request := range requests {
		go func(request *http.Request) {
			defer wg.Done()
			rr := httptest.NewRecorder()
			handler.ServeHTTP(rr, request)

			if status := rr.Code; status != http.StatusOK {
				t.Error("Handler returned wrong status code",
					"expected", http.StatusOK,
					"got", status,
				)
			}
		}(request)
	}

	wg.Wait()

	f, err := os.Open(cacheDir)
	defer f.Close()
	if err != nil {
		t.Error(err)
	}
	files, err := f.Readdir(-1)
	if err != nil {
		t.Error(err)
	}
	var totalSize int64
	for _, fileinfo := range files {
		size := fileinfo.Size()
		if size != 1024 {
			t.Error("Expected all files to be 1024 bytes.", "Got", size)
		}
		totalSize += fileinfo.Size()
	}

	// Test that purging worked and kept cache size in check.
	if upperBound := int64(NumUploads) * 1024 * 1024; totalSize > upperBound {
		t.Error("Cache size too big. Expected at most", upperBound, "got",
			totalSize)
	}
}

func TestUploadSameFileConcurrently(t *testing.T) {
	cacheDir := createTmpDir(t)
	defer os.RemoveAll(cacheDir)

	data, hash := randomDataAndHash(1024)
	r, err := http.NewRequest("PUT", "/cas/"+hash, bytes.NewReader(data))
	if err != nil {
		t.Error(err)
	}

	e := NewEnsureSpacer(1, 1)
	h := NewHTTPCache(cacheDir, 1024, e)
	handler := http.HandlerFunc(h.CacheHandler)

	var wg sync.WaitGroup
	wg.Add(100)
	for i := 0; i < 100; i++ {
		go func(request *http.Request) {
			defer wg.Done()
			rr := httptest.NewRecorder()
			handler.ServeHTTP(rr, request)

			if status := rr.Code; status != http.StatusOK {
				t.Error("Handler returned wrong status code",
					"expected", http.StatusOK,
					"got", status,
				)
			}
		}(r)
	}

	wg.Wait()
}
<|endoftext|>


<commit_before>package firebase

import "sync"

var authInstances = struct {
	sync.Mutex
	m map[string]*Auth
}{
	m: make(map[string]*Auth),
}

// Auth is the entry point for all server-side Firebase Authentication actions.
//
// You can get an instance of Auth via GetInstance(*App) and then use it to
// perform a variety of authentication-related operations, including generating
// custom tokens for use by client-side code, verifying Firebase ID Tokens
// received from clients, or creating new App instances that are scoped to a
// particular authentication UID.
type Auth struct {
	app *App
}

// GetAuth gets the Auth instance for the default App.
func GetAuth() (*Auth, error) {
	app, err := GetApp()
	if err != nil {
		return nil, err
	}
	return GetAuthWithApp(app)
}

// GetAuthWithApp gets an instance of Auth for a specific App.
func GetAuthWithApp(app *App) (*Auth, error) {
	appName := app.name
	authInstances.Lock()
	defer authInstances.Unlock()
	if _, ok := authInstances.m[appName]; !ok {
		authInstances.m[appName] = &Auth{app: app}
	}
	return authInstances.m[appName], nil
}

// CreateCustomToken creates a Firebase Custom Token associated with the given
// UID and additionally containing the specified developerClaims.  This token
// can then be provided back to a client application for use with the
// signInWithCustomToken authentication API.
//
// The UID identifies the user to other Firebase services (Firebase Database,
// Storage, etc.) and should be less than 128 characters.
// The developer claims are optional, additional claims to be stored in the
// token.  The claims must be serializable to JSON.
func (a *Auth) CreateCustomToken(uid string, developerClaims *Claims) (string, error) {
	if a.app.options.ServiceAccountCredential == nil {
		if err := a.app.options.ensureServiceAccount(); err != nil {
			return "", err
		}
	}
	c := a.app.options.ServiceAccountCredential
	return createSignedCustomAuthTokenForUser(uid, developerClaims, c.ClientEmail, c.PrivateKey)
}

// VerifyIDToken parses and verifies a Firebase ID Token.
//
// A Firebase application can identify itself to a trusted backend server by
// sending its Firebase ID Token (accessible via the getToken API in the
// Firebase Authentication client) with its request.
//
// The backend server can then use the VerifyIDToken() method to verify the
// token is valid, meaning: the token is properly signed, has not expired,
// and it was issued for the project associated with this Auth instance
// (which by default is extracted from your service account).
func (a *Auth) VerifyIDToken(tokenString string) (*Token, error) {
	if a.app.options.ServiceAccountCredential == nil {
		if err := a.app.options.ensureServiceAccount(); err != nil {
			return nil, err
		}
	}
	projectID := a.app.options.ServiceAccountCredential.ProjectID
	return verify(projectID, tokenString)
}
<commit_msg>remove redundant check on ServiceAccountCredential<commit_after>package firebase

import "sync"

var authInstances = struct {
	sync.Mutex
	m map[string]*Auth
}{
	m: make(map[string]*Auth),
}

// Auth is the entry point for all server-side Firebase Authentication actions.
//
// You can get an instance of Auth via GetInstance(*App) and then use it to
// perform a variety of authentication-related operations, including generating
// custom tokens for use by client-side code, verifying Firebase ID Tokens
// received from clients, or creating new App instances that are scoped to a
// particular authentication UID.
type Auth struct {
	app *App
}

// GetAuth gets the Auth instance for the default App.
func GetAuth() (*Auth, error) {
	app, err := GetApp()
	if err != nil {
		return nil, err
	}
	return GetAuthWithApp(app)
}

// GetAuthWithApp gets an instance of Auth for a specific App.
func GetAuthWithApp(app *App) (*Auth, error) {
	appName := app.name
	authInstances.Lock()
	defer authInstances.Unlock()
	if _, ok := authInstances.m[appName]; !ok {
		authInstances.m[appName] = &Auth{app: app}
	}
	return authInstances.m[appName], nil
}

// CreateCustomToken creates a Firebase Custom Token associated with the given
// UID and additionally containing the specified developerClaims.  This token
// can then be provided back to a client application for use with the
// signInWithCustomToken authentication API.
//
// The UID identifies the user to other Firebase services (Firebase Database,
// Storage, etc.) and should be less than 128 characters.
// The developer claims are optional, additional claims to be stored in the
// token.  The claims must be serializable to JSON.
func (a *Auth) CreateCustomToken(uid string, developerClaims *Claims) (string, error) {
	if err := a.app.options.ensureServiceAccount(); err != nil {
		return "", err
	}
	c := a.app.options.ServiceAccountCredential
	return createSignedCustomAuthTokenForUser(uid, developerClaims, c.ClientEmail, c.PrivateKey)
}

// VerifyIDToken parses and verifies a Firebase ID Token.
//
// A Firebase application can identify itself to a trusted backend server by
// sending its Firebase ID Token (accessible via the getToken API in the
// Firebase Authentication client) with its request.
//
// The backend server can then use the VerifyIDToken() method to verify the
// token is valid, meaning: the token is properly signed, has not expired,
// and it was issued for the project associated with this Auth instance
// (which by default is extracted from your service account).
func (a *Auth) VerifyIDToken(tokenString string) (*Token, error) {
	if err := a.app.options.ensureServiceAccount(); err != nil {
		return nil, err
	}
	projectID := a.app.options.ServiceAccountCredential.ProjectID
	return verify(projectID, tokenString)
}
<|endoftext|>


<commit_before>// Copyright ©2014 The gonum 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 optimize

import (
	"fmt"
	"math"
	"time"

	"github.com/gonum/floats"
	"github.com/gonum/matrix/mat64"
)

// Local finds a local minimum of a function using a sequential algorithm.
// In order to maximize a function, multiply the output by -1.
//
// The first argument is of Function type representing the function to be minimized.
// Type switching is used to see if the function implements Gradient, FunctionGradient
// and Statuser.
//
// The second argument is the initial location at which to start the minimization.
// The initial location must be supplied, and must have a length equal to the
// problem dimension.
//
// The third argument contains the settings for the minimization. It is here that
// gradient tolerance, etc. are specified. The DefaultSettings() function
// can be called for a Settings struct with the default values initialized.
// If settings == nil, the default settings are used. Please see the documentation
// for the Settings structure for more information. The optimization Method used
// may also contain settings, see documentation for the appropriate optimizer.
//
// The final argument is the optimization method to use. If method == nil, then
// an appropriate default is chosen based on the properties of the other arguments
// (dimension, gradient-free or gradient-based, etc.). The optimization
// methods in this package are designed such that reasonable defaults occur
// if options are not specified explicitly. For example, the code
//  method := &Bfgs{}
// creates a pointer to a new Bfgs struct. When minimize is called, the settings
// in the method will be populated with default values. The methods are also
// designed such that they can be reused in future calls to method.
//
// Local returns a Result struct and any error that occurred. Please see the
// documentation of Result for more information.
//
// Please be aware that the default behavior of Local is to find the minimum.
// For certain functions and optimization methods, this process can take many
// function evaluations. If you would like to put limits on this, for example
// maximum runtime or maximum function evaluations, please modify the Settings
// input struct.
func Local(f Function, initX []float64, settings *Settings, method Method) (*Result, error) {
	if len(initX) == 0 {
		panic("optimize: initial X has zero length")
	}

	startTime := time.Now()
	funcInfo := newFunctionInfo(f)
	if method == nil {
		method = getDefaultMethod(funcInfo)
	}
	if err := funcInfo.satisfies(method); err != nil {
		return nil, err
	}

	if funcInfo.IsStatuser {
		_, err := funcInfo.statuser.Status()
		if err != nil {
			return nil, err
		}
	}

	if settings == nil {
		settings = DefaultSettings()
	}

	if settings.Recorder != nil {
		// Initialize Recorder first. If it fails, we avoid the (possibly
		// time-consuming) evaluation of F and DF at the starting location.
		err := settings.Recorder.Init(&funcInfo.FunctionInfo)
		if err != nil {
			return nil, err
		}
	}

	stats := &Stats{}
	optLoc, evalType, err := getStartingLocation(funcInfo, method, initX, stats, settings)
	if err != nil {
		return nil, err
	}

	if settings.FunctionConverge != nil {
		settings.FunctionConverge.Init(optLoc.F)
	}

	// Runtime is the only Stats field that needs to be updated here.
	stats.Runtime = time.Since(startTime)
	// Send optLoc to Recorder before checking it for convergence.
	if settings.Recorder != nil {
		err = settings.Recorder.Record(optLoc, evalType, InitIteration, stats)
	}

	// Check if the starting location satisfies the convergence criteria.
	status := checkConvergence(optLoc, InitIteration, stats, settings)
	if status == NotTerminated && err == nil {
		// The starting location is not good enough, we need to perform a
		// minimization. The optimal location will be stored in-place in
		// optLoc.
		status, err = minimize(settings, method, funcInfo, stats, optLoc, startTime)
	}

	if settings.Recorder != nil && err == nil {
		// Send the optimal location to Recorder.
		err = settings.Recorder.Record(optLoc, NoEvaluation, PostIteration, stats)
	}
	stats.Runtime = time.Since(startTime)
	return &Result{
		Location: *optLoc,
		Stats:    *stats,
		Status:   status,
	}, err
}

func minimize(settings *Settings, method Method, funcInfo *functionInfo, stats *Stats, optLoc *Location, startTime time.Time) (status Status, err error) {
	loc := &Location{}
	copyLocation(loc, optLoc)
	xNext := make([]float64, len(loc.X))

	methodStatus, methodIsStatuser := method.(Statuser)

	evalType, iterType, err := method.Init(loc, &funcInfo.FunctionInfo, xNext)
	if err != nil {
		return Failure, err
	}

	for {
		if funcInfo.IsStatuser {
			// Check the function status before evaluating.
			status, err = funcInfo.statuser.Status()
			if err != nil || status != NotTerminated {
				return
			}
		}

		// Perform evalType evaluation of the function at xNext and store the
		// result in location.
		evaluate(funcInfo, evalType, xNext, loc, stats)
		// Update the stats and optLoc.
		update(loc, optLoc, stats, iterType, startTime)
		// Get the convergence status before recording the new location.
		status = checkConvergence(optLoc, iterType, stats, settings)

		if settings.Recorder != nil {
			err = settings.Recorder.Record(loc, evalType, iterType, stats)
			if err != nil {
				if status == NotTerminated {
					status = Failure
				}
				return
			}
		}

		if status != NotTerminated {
			return
		}

		if methodIsStatuser {
			status, err = methodStatus.Status()
			if err != nil || status != NotTerminated {
				return
			}
		}

		// Find the next location (stored in-place into xNext).
		evalType, iterType, err = method.Iterate(loc, xNext)
		if err != nil {
			status = Failure
			return
		}
	}
	panic("optimize: unreachable")
}

func copyLocation(dst, src *Location) {
	dst.X = resize(dst.X, len(src.X))
	copy(dst.X, src.X)

	dst.F = src.F

	dst.Gradient = resize(dst.Gradient, len(src.Gradient))
	copy(dst.Gradient, src.Gradient)

	if src.Hessian != nil {
		if dst.Hessian == nil || dst.Hessian.Symmetric() != len(src.X) {
			dst.Hessian = mat64.NewSymDense(len(src.X), nil)
		}
		dst.Hessian.CopySym(src.Hessian)
	}
}

func getDefaultMethod(funcInfo *functionInfo) Method {
	if funcInfo.IsGradient {
		return &BFGS{}
	}
	return &NelderMead{}
}

// getStartingLocation allocates and initializes the starting location for the minimization.
func getStartingLocation(funcInfo *functionInfo, method Method, initX []float64, stats *Stats, settings *Settings) (*Location, EvaluationType, error) {
	dim := len(initX)
	loc := &Location{
		X: make([]float64, dim),
	}
	copy(loc.X, initX)
	if method.Needs().Gradient {
		loc.Gradient = make([]float64, dim)
	}
	if method.Needs().Hessian {
		loc.Hessian = mat64.NewSymDense(dim, nil)
	}

	evalType := NoEvaluation
	if settings.UseInitialData {
		loc.F = settings.InitialValue
		if loc.Gradient != nil {
			initG := settings.InitialGradient
			if initG == nil {
				panic("optimize: initial gradient is nil")
			}
			if len(initG) != dim {
				panic("optimize: initial gradient size mismatch")
			}
			copy(loc.Gradient, initG)
		}
		if loc.Hessian != nil {
			initH := settings.InitialHessian
			if initH == nil {
				panic("optimize: initial Hessian is nil")
			}
			if initH.Symmetric() != dim {
				panic("optimize: initial Hessian size mismatch")
			}
			loc.Hessian.CopySym(initH)
		}
	} else {
		switch {
		case loc.Hessian != nil:
			evalType = FuncGradHessEvaluation
		case loc.Gradient != nil:
			evalType = FuncGradEvaluation
		default:
			evalType = FuncEvaluation
		}
		evaluate(funcInfo, evalType, loc.X, loc, stats)
	}

	if math.IsNaN(loc.F) {
		return loc, evalType, ErrNaN
	}
	if math.IsInf(loc.F, 1) {
		return loc, evalType, ErrInf
	}
	for _, v := range loc.Gradient {
		if math.IsInf(v, 0) {
			return loc, evalType, ErrGradInf
		}
		if math.IsNaN(v) {
			return loc, evalType, ErrGradNaN
		}
	}

	return loc, evalType, nil
}

func checkConvergence(loc *Location, iterType IterationType, stats *Stats, settings *Settings) Status {
	if iterType == MajorIteration || iterType == InitIteration {
		if loc.Gradient != nil {
			norm := floats.Norm(loc.Gradient, math.Inf(1))
			if norm < settings.GradientThreshold {
				return GradientThreshold
			}
		}
		if loc.F < settings.FunctionThreshold {
			return FunctionThreshold
		}
	}

	if iterType == MajorIteration && settings.FunctionConverge != nil {
		status := settings.FunctionConverge.FunctionConverged(loc.F)
		if status != NotTerminated {
			return status
		}
	}

	// Check every step for negative infinity because it could break the
	// linesearches and -inf is the best you can do anyway.
	if math.IsInf(loc.F, -1) {
		return FunctionNegativeInfinity
	}

	if settings.FuncEvaluations > 0 {
		totalFun := stats.FuncEvaluations + stats.FuncGradEvaluations + stats.FuncGradHessEvaluations
		if totalFun >= settings.FuncEvaluations {
			return FunctionEvaluationLimit
		}
	}

	if settings.GradEvaluations > 0 {
		totalGrad := stats.GradEvaluations + stats.FuncGradEvaluations + stats.FuncGradHessEvaluations
		if totalGrad >= settings.GradEvaluations {
			return GradientEvaluationLimit
		}
	}

	if settings.HessEvaluations > 0 {
		totalHess := stats.HessEvaluations + stats.FuncGradHessEvaluations
		if totalHess >= settings.HessEvaluations {
			return HessianEvaluationLimit
		}
	}

	if settings.Runtime > 0 {
		// TODO(vladimir-ch): It would be nice to update Runtime here.
		if stats.Runtime >= settings.Runtime {
			return RuntimeLimit
		}
	}

	if iterType == MajorIteration && settings.MajorIterations > 0 {
		if stats.MajorIterations >= settings.MajorIterations {
			return IterationLimit
		}
	}
	return NotTerminated
}

// invalidate marks unused fields of Location with NaNs. It exists as a help
// for implementers to detect silent bugs in Methods using inconsistent
// Location, e.g., using Gradient after FuncEvaluation request. It is the
// responsibility of Method to make Location valid again.
func invalidate(loc *Location, f, grad, hess bool) {
	if f {
		loc.F = math.NaN()
	}
	if grad && loc.Gradient != nil {
		loc.Gradient[0] = math.NaN()
	}
	if hess && loc.Hessian != nil {
		loc.Hessian.SetSym(0, 0, math.NaN())
	}
}

// evaluate evaluates the function given by funcInfo at xNext, stores the
// answer into loc and updates stats. If loc.X is not equal to xNext, then
// unused fields of loc are set to NaN.
// evaluate panics if the function does not support the requested evalType.
func evaluate(funcInfo *functionInfo, evalType EvaluationType, xNext []float64, loc *Location, stats *Stats) {
	different := !floats.Equal(loc.X, xNext)
	if different {
		copy(loc.X, xNext)
	}
	switch evalType {
	case FuncEvaluation:
		if different {
			invalidate(loc, false, true, true)
		}
		loc.F = funcInfo.function.Func(loc.X)
		stats.FuncEvaluations++
		return
	case GradEvaluation:
		if funcInfo.IsGradient {
			if different {
				invalidate(loc, true, false, true)
			}
			funcInfo.gradient.Grad(loc.X, loc.Gradient)
			stats.GradEvaluations++
			return
		}
		if funcInfo.IsFunctionGradient {
			if different {
				invalidate(loc, false, false, true)
			}
			loc.F = funcInfo.functionGradient.FuncGrad(loc.X, loc.Gradient)
			stats.FuncGradEvaluations++
			return
		}
		if funcInfo.IsFunctionGradientHessian {
			if loc.Hessian == nil {
				loc.Hessian = mat64.NewSymDense(len(loc.X), nil)
			}
			loc.F = funcInfo.functionGradientHessian.FuncGradHess(loc.X, loc.Gradient, loc.Hessian)
			stats.FuncGradHessEvaluations++
			return
		}
	case HessEvaluation:
		if funcInfo.IsHessian {
			if different {
				invalidate(loc, true, true, false)
			}
			funcInfo.hessian.Hess(loc.X, loc.Hessian)
			stats.HessEvaluations++
			return
		}
		if funcInfo.IsFunctionGradientHessian {
			if loc.Gradient == nil {
				loc.Gradient = make([]float64, len(loc.X))
			}
			loc.F = funcInfo.functionGradientHessian.FuncGradHess(loc.X, loc.Gradient, loc.Hessian)
			stats.FuncGradHessEvaluations++
			return
		}
	case FuncGradEvaluation:
		if funcInfo.IsFunctionGradient {
			if different {
				invalidate(loc, false, false, true)
			}
			loc.F = funcInfo.functionGradient.FuncGrad(loc.X, loc.Gradient)
			stats.FuncGradEvaluations++
			return
		}
		if funcInfo.IsGradient {
			if different {
				invalidate(loc, false, false, true)
			}
			loc.F = funcInfo.function.Func(loc.X)
			stats.FuncEvaluations++
			funcInfo.gradient.Grad(loc.X, loc.Gradient)
			stats.GradEvaluations++
			return
		}
		if funcInfo.IsFunctionGradientHessian {
			if loc.Hessian == nil {
				loc.Hessian = mat64.NewSymDense(len(loc.X), nil)
			}
			loc.F = funcInfo.functionGradientHessian.FuncGradHess(loc.X, loc.Gradient, loc.Hessian)
			stats.FuncGradHessEvaluations++
			return
		}
	case FuncGradHessEvaluation:
		if funcInfo.IsFunctionGradientHessian {
			loc.F = funcInfo.functionGradientHessian.FuncGradHess(loc.X, loc.Gradient, loc.Hessian)
			stats.FuncGradHessEvaluations++
			return
		}
		if funcInfo.IsGradient && funcInfo.IsHessian {
			loc.F = funcInfo.function.Func(loc.X)
			stats.FuncEvaluations++
			funcInfo.gradient.Grad(loc.X, loc.Gradient)
			stats.GradEvaluations++
			funcInfo.hessian.Hess(loc.X, loc.Hessian)
			stats.HessEvaluations++
			return
		}
	case NoEvaluation:
		if different {
			// Optimizers should not request NoEvaluation at a new location.
			// The intent and therefore an appropriate action are both unclear.
			panic("optimize: no evaluation requested at new location")
		}
		return
	default:
		panic(fmt.Sprintf("optimize: unknown evaluation type %v", evalType))
	}
	panic(fmt.Sprintf("optimize: objective function does not support %v", evalType))
}

// update updates the stats given the new evaluation
func update(loc *Location, optLoc *Location, stats *Stats, iterType IterationType, startTime time.Time) {
	if iterType == MajorIteration {
		stats.MajorIterations++
	}
	if loc.F <= optLoc.F {
		copyLocation(optLoc, loc)
	}
	stats.Runtime = time.Since(startTime)
}
<commit_msg>Simplify evaluate() and invalidate()<commit_after>// Copyright ©2014 The gonum 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 optimize

import (
	"fmt"
	"math"
	"time"

	"github.com/gonum/floats"
	"github.com/gonum/matrix/mat64"
)

// Local finds a local minimum of a function using a sequential algorithm.
// In order to maximize a function, multiply the output by -1.
//
// The first argument is of Function type representing the function to be minimized.
// Type switching is used to see if the function implements Gradient, FunctionGradient
// and Statuser.
//
// The second argument is the initial location at which to start the minimization.
// The initial location must be supplied, and must have a length equal to the
// problem dimension.
//
// The third argument contains the settings for the minimization. It is here that
// gradient tolerance, etc. are specified. The DefaultSettings() function
// can be called for a Settings struct with the default values initialized.
// If settings == nil, the default settings are used. Please see the documentation
// for the Settings structure for more information. The optimization Method used
// may also contain settings, see documentation for the appropriate optimizer.
//
// The final argument is the optimization method to use. If method == nil, then
// an appropriate default is chosen based on the properties of the other arguments
// (dimension, gradient-free or gradient-based, etc.). The optimization
// methods in this package are designed such that reasonable defaults occur
// if options are not specified explicitly. For example, the code
//  method := &Bfgs{}
// creates a pointer to a new Bfgs struct. When minimize is called, the settings
// in the method will be populated with default values. The methods are also
// designed such that they can be reused in future calls to method.
//
// Local returns a Result struct and any error that occurred. Please see the
// documentation of Result for more information.
//
// Please be aware that the default behavior of Local is to find the minimum.
// For certain functions and optimization methods, this process can take many
// function evaluations. If you would like to put limits on this, for example
// maximum runtime or maximum function evaluations, please modify the Settings
// input struct.
func Local(f Function, initX []float64, settings *Settings, method Method) (*Result, error) {
	if len(initX) == 0 {
		panic("optimize: initial X has zero length")
	}

	startTime := time.Now()
	funcInfo := newFunctionInfo(f)
	if method == nil {
		method = getDefaultMethod(funcInfo)
	}
	if err := funcInfo.satisfies(method); err != nil {
		return nil, err
	}

	if funcInfo.IsStatuser {
		_, err := funcInfo.statuser.Status()
		if err != nil {
			return nil, err
		}
	}

	if settings == nil {
		settings = DefaultSettings()
	}

	if settings.Recorder != nil {
		// Initialize Recorder first. If it fails, we avoid the (possibly
		// time-consuming) evaluation of F and DF at the starting location.
		err := settings.Recorder.Init(&funcInfo.FunctionInfo)
		if err != nil {
			return nil, err
		}
	}

	stats := &Stats{}
	optLoc, evalType, err := getStartingLocation(funcInfo, method, initX, stats, settings)
	if err != nil {
		return nil, err
	}

	if settings.FunctionConverge != nil {
		settings.FunctionConverge.Init(optLoc.F)
	}

	// Runtime is the only Stats field that needs to be updated here.
	stats.Runtime = time.Since(startTime)
	// Send optLoc to Recorder before checking it for convergence.
	if settings.Recorder != nil {
		err = settings.Recorder.Record(optLoc, evalType, InitIteration, stats)
	}

	// Check if the starting location satisfies the convergence criteria.
	status := checkConvergence(optLoc, InitIteration, stats, settings)
	if status == NotTerminated && err == nil {
		// The starting location is not good enough, we need to perform a
		// minimization. The optimal location will be stored in-place in
		// optLoc.
		status, err = minimize(settings, method, funcInfo, stats, optLoc, startTime)
	}

	if settings.Recorder != nil && err == nil {
		// Send the optimal location to Recorder.
		err = settings.Recorder.Record(optLoc, NoEvaluation, PostIteration, stats)
	}
	stats.Runtime = time.Since(startTime)
	return &Result{
		Location: *optLoc,
		Stats:    *stats,
		Status:   status,
	}, err
}

func minimize(settings *Settings, method Method, funcInfo *functionInfo, stats *Stats, optLoc *Location, startTime time.Time) (status Status, err error) {
	loc := &Location{}
	copyLocation(loc, optLoc)
	xNext := make([]float64, len(loc.X))

	methodStatus, methodIsStatuser := method.(Statuser)

	evalType, iterType, err := method.Init(loc, &funcInfo.FunctionInfo, xNext)
	if err != nil {
		return Failure, err
	}

	for {
		if funcInfo.IsStatuser {
			// Check the function status before evaluating.
			status, err = funcInfo.statuser.Status()
			if err != nil || status != NotTerminated {
				return
			}
		}

		// Perform evalType evaluation of the function at xNext and store the
		// result in location.
		evaluate(funcInfo, evalType, xNext, loc, stats)
		// Update the stats and optLoc.
		update(loc, optLoc, stats, iterType, startTime)
		// Get the convergence status before recording the new location.
		status = checkConvergence(optLoc, iterType, stats, settings)

		if settings.Recorder != nil {
			err = settings.Recorder.Record(loc, evalType, iterType, stats)
			if err != nil {
				if status == NotTerminated {
					status = Failure
				}
				return
			}
		}

		if status != NotTerminated {
			return
		}

		if methodIsStatuser {
			status, err = methodStatus.Status()
			if err != nil || status != NotTerminated {
				return
			}
		}

		// Find the next location (stored in-place into xNext).
		evalType, iterType, err = method.Iterate(loc, xNext)
		if err != nil {
			status = Failure
			return
		}
	}
	panic("optimize: unreachable")
}

func copyLocation(dst, src *Location) {
	dst.X = resize(dst.X, len(src.X))
	copy(dst.X, src.X)

	dst.F = src.F

	dst.Gradient = resize(dst.Gradient, len(src.Gradient))
	copy(dst.Gradient, src.Gradient)

	if src.Hessian != nil {
		if dst.Hessian == nil || dst.Hessian.Symmetric() != len(src.X) {
			dst.Hessian = mat64.NewSymDense(len(src.X), nil)
		}
		dst.Hessian.CopySym(src.Hessian)
	}
}

func getDefaultMethod(funcInfo *functionInfo) Method {
	if funcInfo.IsGradient {
		return &BFGS{}
	}
	return &NelderMead{}
}

// getStartingLocation allocates and initializes the starting location for the minimization.
func getStartingLocation(funcInfo *functionInfo, method Method, initX []float64, stats *Stats, settings *Settings) (*Location, EvaluationType, error) {
	dim := len(initX)
	loc := &Location{
		X: make([]float64, dim),
	}
	copy(loc.X, initX)
	if method.Needs().Gradient {
		loc.Gradient = make([]float64, dim)
	}
	if method.Needs().Hessian {
		loc.Hessian = mat64.NewSymDense(dim, nil)
	}

	evalType := NoEvaluation
	if settings.UseInitialData {
		loc.F = settings.InitialValue
		if loc.Gradient != nil {
			initG := settings.InitialGradient
			if initG == nil {
				panic("optimize: initial gradient is nil")
			}
			if len(initG) != dim {
				panic("optimize: initial gradient size mismatch")
			}
			copy(loc.Gradient, initG)
		}
		if loc.Hessian != nil {
			initH := settings.InitialHessian
			if initH == nil {
				panic("optimize: initial Hessian is nil")
			}
			if initH.Symmetric() != dim {
				panic("optimize: initial Hessian size mismatch")
			}
			loc.Hessian.CopySym(initH)
		}
	} else {
		switch {
		case loc.Hessian != nil:
			evalType = FuncGradHessEvaluation
		case loc.Gradient != nil:
			evalType = FuncGradEvaluation
		default:
			evalType = FuncEvaluation
		}
		evaluate(funcInfo, evalType, loc.X, loc, stats)
	}

	if math.IsNaN(loc.F) {
		return loc, evalType, ErrNaN
	}
	if math.IsInf(loc.F, 1) {
		return loc, evalType, ErrInf
	}
	for _, v := range loc.Gradient {
		if math.IsInf(v, 0) {
			return loc, evalType, ErrGradInf
		}
		if math.IsNaN(v) {
			return loc, evalType, ErrGradNaN
		}
	}

	return loc, evalType, nil
}

func checkConvergence(loc *Location, iterType IterationType, stats *Stats, settings *Settings) Status {
	if iterType == MajorIteration || iterType == InitIteration {
		if loc.Gradient != nil {
			norm := floats.Norm(loc.Gradient, math.Inf(1))
			if norm < settings.GradientThreshold {
				return GradientThreshold
			}
		}
		if loc.F < settings.FunctionThreshold {
			return FunctionThreshold
		}
	}

	if iterType == MajorIteration && settings.FunctionConverge != nil {
		status := settings.FunctionConverge.FunctionConverged(loc.F)
		if status != NotTerminated {
			return status
		}
	}

	// Check every step for negative infinity because it could break the
	// linesearches and -inf is the best you can do anyway.
	if math.IsInf(loc.F, -1) {
		return FunctionNegativeInfinity
	}

	if settings.FuncEvaluations > 0 {
		totalFun := stats.FuncEvaluations + stats.FuncGradEvaluations + stats.FuncGradHessEvaluations
		if totalFun >= settings.FuncEvaluations {
			return FunctionEvaluationLimit
		}
	}

	if settings.GradEvaluations > 0 {
		totalGrad := stats.GradEvaluations + stats.FuncGradEvaluations + stats.FuncGradHessEvaluations
		if totalGrad >= settings.GradEvaluations {
			return GradientEvaluationLimit
		}
	}

	if settings.HessEvaluations > 0 {
		totalHess := stats.HessEvaluations + stats.FuncGradHessEvaluations
		if totalHess >= settings.HessEvaluations {
			return HessianEvaluationLimit
		}
	}

	if settings.Runtime > 0 {
		// TODO(vladimir-ch): It would be nice to update Runtime here.
		if stats.Runtime >= settings.Runtime {
			return RuntimeLimit
		}
	}

	if iterType == MajorIteration && settings.MajorIterations > 0 {
		if stats.MajorIterations >= settings.MajorIterations {
			return IterationLimit
		}
	}
	return NotTerminated
}

// invalidate marks all fields of Location with NaNs and it is the
// responsibility of Method to issue such EvaluationTypes that make Location
// valid again. Invalidation is done internally as a help for implementers to
// detect silent bugs in Methods using inconsistent Location, e.g., using
// Gradient without a GradEvaluation request.
func invalidate(loc *Location) {
	loc.F = math.NaN()
	if loc.Gradient != nil {
		loc.Gradient[0] = math.NaN()
	}
	if loc.Hessian != nil {
		loc.Hessian.SetSym(0, 0, math.NaN())
	}
}

// evaluate evaluates the function given by f at xNext, stores the answer into
// loc and updates stats. If loc.X is not equal to xNext, then unused fields of
// loc are set to NaN.
// evaluate panics if the function does not support the requested evalType.
func evaluate(f *functionInfo, evalType EvaluationType, xNext []float64, loc *Location, stats *Stats) {
	different := !floats.Equal(loc.X, xNext)
	if different {
		if evalType == NoEvaluation {
			// Optimizers should not request NoEvaluation at a new location.
			// The intent and therefore an appropriate action are both unclear.
			panic("optimize: no evaluation requested at new location")
		}
		invalidate(loc)
		copy(loc.X, xNext)
	}

	if evalType == NoEvaluation {
		return
	}

	if evalType == FuncGradHessEvaluation && f.IsFunctionGradientHessian {
		loc.F = f.functionGradientHessian.FuncGradHess(loc.X, loc.Gradient, loc.Hessian)
		stats.FuncGradHessEvaluations++
		return
	}
	if evalType == FuncGradEvaluation && f.IsFunctionGradient {
		loc.F = f.functionGradient.FuncGrad(loc.X, loc.Gradient)
		stats.FuncGradEvaluations++
		return
	}

	if evalType == FuncGradHessEvaluation && f.IsFunctionGradient {
		loc.F = f.functionGradient.FuncGrad(loc.X, loc.Gradient)
		stats.FuncGradEvaluations++
		evalType = HessEvaluation
	}
	if evalType&FuncEvaluation != 0 {
		loc.F = f.function.Func(loc.X)
		stats.FuncEvaluations++
		evalType &= ^FuncEvaluation
	}
	if evalType&GradEvaluation != 0 {
		f.gradient.Grad(loc.X, loc.Gradient)
		stats.GradEvaluations++
		evalType &= ^GradEvaluation
	}
	if evalType&HessEvaluation != 0 {
		f.hessian.Hess(loc.X, loc.Hessian)
		stats.HessEvaluations++
		evalType &= ^HessEvaluation
	}

	if evalType != NoEvaluation {
		panic(fmt.Sprintf("optimize: unknown evaluation type %v", evalType))
	}
}

// update updates the stats given the new evaluation
func update(loc *Location, optLoc *Location, stats *Stats, iterType IterationType, startTime time.Time) {
	if iterType == MajorIteration {
		stats.MajorIterations++
	}
	if loc.F <= optLoc.F {
		copyLocation(optLoc, loc)
	}
	stats.Runtime = time.Since(startTime)
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Frank Braun <frank@cryptogroup.net>
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

// markup serves markup files as HTML on localhost.
package markup

import (
	"fmt"
	"net"
	"net/http"

	"github.com/fsnotify/fsnotify"
	"github.com/mutecomm/mute/util/browser"
)

var html []byte

type Renderer interface {
	Render(filename string) ([]byte, error)
}

func Serve(r Renderer, filename string) error {
	// render markdown
	var err error
	html, err = r.Render(filename)
	if err != nil {
		return err
	}
	// watch markdown file for changes and rerender if necessary
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return err
	}
	defer watcher.Close()
	if err := watcher.Add(filename); err != nil {
		return err
	}
	go func() {
		for {
			var err error
			select {
			case event := <-watcher.Events:
				fmt.Println("event:", event)
				if event.Op&fsnotify.Remove == fsnotify.Remove {
					if err := watcher.Add(filename); err != nil {
						fmt.Println("error:", err)
					}
					html, err = r.Render(filename)
					if err != nil {
						fmt.Println("error:", err)
					}
				}
				if event.Op&fsnotify.Write == fsnotify.Write {
					html, err = r.Render(filename)
					if err != nil {
						fmt.Println("error:", err)
					}
				}
			case err := <-watcher.Errors:
				fmt.Println("error:", err)
			}
		}
	}()
	// serve markdown
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		w.Write(html)
	})
	listener, err := net.Listen("tcp", ":0")
	if err != nil {
		return err
	}
	port := listener.Addr().(*net.TCPAddr).Port
	addr := fmt.Sprintf("http://localhost:%d/", port)
	fmt.Println("serving at", addr)
	go browser.Open(addr)
	return http.Serve(listener, nil)
}
<commit_msg>markup: add documentation<commit_after>// Copyright (c) 2017 Frank Braun <frank@cryptogroup.net>
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

// Package markup serves markup files as HTML on localhost.
package markup

import (
	"fmt"
	"net"
	"net/http"

	"github.com/fsnotify/fsnotify"
	"github.com/mutecomm/mute/util/browser"
)

var html []byte

// Renderer is the markup interface.
type Renderer interface {
	Render(filename string) ([]byte, error)
}

// Serve serves markup in file filename rendered with r on localhost.
// It automatically rerenders the markup if the file is changed.
// It also tries to open a browser.
func Serve(r Renderer, filename string) error {
	// render markdown
	var err error
	html, err = r.Render(filename)
	if err != nil {
		return err
	}
	// watch markdown file for changes and rerender if necessary
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return err
	}
	defer watcher.Close()
	if err := watcher.Add(filename); err != nil {
		return err
	}
	go func() {
		for {
			var err error
			select {
			case event := <-watcher.Events:
				fmt.Println("event:", event)
				if event.Op&fsnotify.Remove == fsnotify.Remove {
					if err := watcher.Add(filename); err != nil {
						fmt.Println("error:", err)
					}
					html, err = r.Render(filename)
					if err != nil {
						fmt.Println("error:", err)
					}
				}
				if event.Op&fsnotify.Write == fsnotify.Write {
					html, err = r.Render(filename)
					if err != nil {
						fmt.Println("error:", err)
					}
				}
			case err := <-watcher.Errors:
				fmt.Println("error:", err)
			}
		}
	}()
	// serve markdown
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		w.Header().Set("Content-Type", "text/html; charset=utf-8")
		w.Write(html)
	})
	listener, err := net.Listen("tcp", ":0")
	if err != nil {
		return err
	}
	port := listener.Addr().(*net.TCPAddr).Port
	addr := fmt.Sprintf("http://localhost:%d/", port)
	fmt.Println("serving at", addr)
	go browser.Open(addr)
	return http.Serve(listener, nil)
}
<|endoftext|>


<commit_before>package campfire

import (
    "bytes"
    "encoding/json"
    "io/ioutil"
    "net"
    "net/http"
    "net/http/httputil"
    "net/url"
    "crypto/tls"
)

type Client struct {
    host    string
    token   string
}

func NewClient(subdomain, token string) *Client {
    return &Client{
        host:   subdomain + ".campfirenow.com",
        token:  token,
    }
}

func (c *Client) Room(id int) *Room {
    return &Room{Client: c, id: id}
}

func (c *Client) User(id int) *User {
    return &User{Client: c, id: id}
}

func (c *Client) Account(id int) *Account {
    return &Account{Client: c, Id: id}
}

func (c *Client) Me() (*User, error) {
    resp, err := c.Get("/users/me")

    if err != nil {
        return nil, err
    }

    out, err := ioutil.ReadAll(resp.Body)

    if err != nil {
        return nil, err
    }

    var fetch struct {
        User *User `json:"user"`
    }

    err = json.Unmarshal(out, &fetch)

    if err != nil {
        return nil, err
    }

    return fetch.User, nil
}

func (c *Client) Get(path string) (*http.Response, error) {
    return c.request("GET", path, []byte(""))
}

func (c *Client) Post(path string, body []byte) (*http.Response, error) {
    return c.request("POST", path, body)
}

func (c *Client) request(method, path string, body []byte) (*http.Response, error) {
    url := &url.URL{
        Scheme: "https",
        Host:   c.host,
        Path:   path,
    }

    conn, err := net.Dial("tcp", url.Host + ":443")

    if err != nil {
        return nil, err
    }

    ssl        := tls.Client(conn, nil)
    httpClient := httputil.NewClientConn(ssl, nil)

    req, err := http.NewRequest(method, url.String(), bytes.NewBuffer(body))
    req.Header.Add("Content-Type", "application/json")
    req.SetBasicAuth(c.token, "X")

    if method == "POST" {
        req.ContentLength = int64(len(body))
    }

    if err != nil {
        return nil, err
    }

    return httpClient.Do(req)
}

func body(resp *http.Response) []byte {
    out, err := ioutil.ReadAll(resp.Body)

    if err != nil {
        return []byte{}
    }

    return out
}
<commit_msg>removing account and applying the body thing i made here<commit_after>package campfire

import (
    "bytes"
    "encoding/json"
    "io/ioutil"
    "net"
    "net/http"
    "net/http/httputil"
    "net/url"
    "crypto/tls"
)

type Client struct {
    host    string
    token   string
}

func NewClient(subdomain, token string) *Client {
    return &Client{
        host:   subdomain + ".campfirenow.com",
        token:  token,
    }
}

func (c *Client) Room(id int) *Room {
    return &Room{Client: c, id: id}
}

func (c *Client) User(id int) *User {
    return &User{Client: c, id: id}
}

func (c *Client) Me() (*User, error) {
    resp, err := c.Get("/users/me")

    if err != nil {
        return nil, err
    }

    var fetch struct {
        User *User `json:"user"`
    }

    err = json.Unmarshal(body(resp), &fetch)

    if err != nil {
        return nil, err
    }

    return fetch.User, nil
}

func (c *Client) Get(path string) (*http.Response, error) {
    return c.request("GET", path, []byte(""))
}

func (c *Client) Post(path string, body []byte) (*http.Response, error) {
    return c.request("POST", path, body)
}

func (c *Client) request(method, path string, body []byte) (*http.Response, error) {
    url := &url.URL{
        Scheme: "https",
        Host:   c.host,
        Path:   path,
    }

    conn, err := net.Dial("tcp", url.Host + ":443")

    if err != nil {
        return nil, err
    }

    ssl        := tls.Client(conn, nil)
    httpClient := httputil.NewClientConn(ssl, nil)

    req, err := http.NewRequest(method, url.String(), bytes.NewBuffer(body))
    req.Header.Add("Content-Type", "application/json")
    req.SetBasicAuth(c.token, "X")

    if method == "POST" {
        req.ContentLength = int64(len(body))
    }

    if err != nil {
        return nil, err
    }

    return httpClient.Do(req)
}

func body(resp *http.Response) []byte {
    out, err := ioutil.ReadAll(resp.Body)

    if err != nil {
        return []byte{}
    }

    return out
}
<|endoftext|>


<commit_before>package zhiro

import (
	"net/http"
)

type Zhiro struct {
	denyFunc http.HandlerFunc
	manager  *ChainManager
    realm Realm
}

type Realm interface{
    GetAuthorization(princ Principal)Authorization
}

func NewZhiro(chain map[string]string) *Zhiro {
	zhiro := &Zhiro{func(w http.ResponseWriter, req *http.Request) {
		http.Redirect(w, req, "/login", 302)
	}, NewChainManager()}
	for key, value := range chain {
		zhiro.manager.CreateChain(key, value)
	}
	return zhiro
}

func (zh *Zhiro) DenyFunc() http.HandlerFunc {
	return zh.denyFunc
}

func (zh *Zhiro) Check(w http.ResponseWriter, req *http.Request) bool {
	return false
}

func (zh *Zhiro) ServeHTTP(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
	if zh.Check(w, req) {
		zh.DenyFunc()(w, req)
		return
	}
	next(w, req)
}
<commit_msg>format<commit_after>package zhiro

import (
	"net/http"
)

type Zhiro struct {
	denyFunc http.HandlerFunc
	manager  *ChainManager
	realm    Realm
}

type Realm interface {
	GetAuthorization(princ Principal) Authorization
}

func NewZhiro(chain map[string]string) *Zhiro {
	zhiro := &Zhiro{func(w http.ResponseWriter, req *http.Request) {
		http.Redirect(w, req, "/login", 302)
	}, NewChainManager()}
	for key, value := range chain {
		zhiro.manager.CreateChain(key, value)
	}
	return zhiro
}

func (zh *Zhiro) DenyFunc() http.HandlerFunc {
	return zh.denyFunc
}

func (zh *Zhiro) Check(w http.ResponseWriter, req *http.Request) bool {
	return false
}

func (zh *Zhiro) ServeHTTP(w http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
	if zh.Check(w, req) {
		zh.DenyFunc()(w, req)
		return
	}
	next(w, req)
}
<|endoftext|>