diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 193536ccea..719d45b396 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -21,6 +21,8 @@ import ( "encoding/json" "fmt" "io" + + "github.com/ethereum/go-ethereum/common" ) // The ABI holds information about a contract's context and available @@ -168,11 +170,11 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { // EventById looks up an event by the first topic hash // returns nil if none was found -func (abi *ABI) EventById(topic []byte) (*Event, error) { +func (abi *ABI) EventById(id common.Hash) (*Event, error) { for _, event := range abi.Events { - if bytes.Equal(event.Id().Bytes(), topic) { + if bytes.Equal(event.Id().Bytes(), id.Bytes()) { return &event, nil } } - return nil, fmt.Errorf("no event with id: %#x", topic) + return nil, fmt.Errorf("no event with id: %#x", id) } diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 60fe104574..8a9cdd8bb9 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -931,3 +931,41 @@ func TestABI_MethodById(t *testing.T) { t.Errorf("Expected error, nil is short to decode data") } } + +func TestABI_EventById(t *testing.T) { + const abiJSON = ` +[ + { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "constant": false, "inputs": [ { "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "approve", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, + { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "constant": false, "inputs": [ { "name": "_from", "type": "address" }, { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, + { "constant": true, "inputs": [], "name": "decimals", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "constant": true, "inputs": [ { "name": "_owner", "type": "address" } ], "name": "balanceOf", "outputs": [ { "name": "balance", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "constant": true, "inputs": [], "name": "symbol", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "constant": false, "inputs": [ { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "transfer", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, + { "constant": true, "inputs": [ { "name": "_owner", "type": "address" }, { "name": "_spender", "type": "address" } ], "name": "allowance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, + { "payable": true, "stateMutability": "payable", "type": "fallback" }, + { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, + { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" } +] +` + abi, err := JSON(strings.NewReader(abiJSON)) + if err != nil { + t.Fatal(err) + } + for name, e := range abi.Events { + a := fmt.Sprintf("%v", e) + e2, err := abi.EventById(e.Id()) + if err != nil { + t.Fatalf("Failed to look up ABI method: %v", err) + } + b := fmt.Sprintf("%v", e2) + if a != b { + t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, e.Id().Hex()) + } + } + // Also test random hash + if _, err := abi.EventById(common.HexToHash("00xea9415385bae08fe9f6dc457b02577166790cde83bb18cc340aac6cb81b824de")); err == nil { + t.Errorf("Expected error, no event with id") + } +} diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go index cb67398995..85a32732db 100755 --- a/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go @@ -35,7 +35,7 @@ const ( ) var reportEvent = func() func(eventType eventType, eventID int32, msg string) { - advAPI32 := syscall.MustLoadDLL("AdvAPI32.dll") + advAPI32 := syscall.MustLoadDLL("advapi32.dll") // lower case to tie in with Go's sysdll registration registerEventSource := advAPI32.MustFindProc("RegisterEventSourceW") sourceName, _ := os.Executable() diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go index fd008364d6..4aaf066501 100755 --- a/vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go @@ -9,6 +9,23 @@ type causer interface { Cause() error } +func errorWithPC(msg string, pc uintptr) string { + s := "" + if fn := runtime.FuncForPC(pc); fn != nil { + file, line := fn.FileLine(pc) + s = fmt.Sprintf("-> %v, %v:%v\n", fn.Name(), file, line) + } + s += msg + "\n\n" + return s +} + +func getPC(callersToSkip int) uintptr { + // Get the PC of Initialize method's caller. + pc := [1]uintptr{} + _ = runtime.Callers(callersToSkip, pc[:]) + return pc[0] +} + // ErrorNode can be an embedded field in a private error object. This field // adds Program Counter support and a 'cause' (reference to a preceding error). // When initializing a error type with this embedded field, initialize the @@ -22,12 +39,7 @@ type ErrorNode struct { // When defining a new error type, have its Error method call this one passing // it the string representation of the error. func (e *ErrorNode) Error(msg string) string { - s := "" - if fn := runtime.FuncForPC(e.pc); fn != nil { - file, line := fn.FileLine(e.pc) - s = fmt.Sprintf("-> %v, %v:%v\n", fn.Name(), file, line) - } - s += msg + "\n\n" + s := errorWithPC(msg, e.pc) if e.cause != nil { s += e.cause.Error() + "\n" } @@ -83,10 +95,8 @@ func (e ErrorNode) Timeout() bool { // value of 3 is very common; but, depending on your code nesting, you may need // a different value. func (ErrorNode) Initialize(cause error, callersToSkip int) ErrorNode { - // Get the PC of Initialize method's caller. - pc := [1]uintptr{} - _ = runtime.Callers(callersToSkip, pc[:]) - return ErrorNode{pc: pc[0], cause: cause} + pc := getPC(callersToSkip) + return ErrorNode{pc: pc, cause: cause} } // Cause walks all the preceding errors and return the originating error. @@ -101,12 +111,53 @@ func Cause(err error) error { return err } +// ErrorNodeNoCause can be an embedded field in a private error object. This field +// adds Program Counter support. +// When initializing a error type with this embedded field, initialize the +// ErrorNodeNoCause field by calling ErrorNodeNoCause{}.Initialize(). +type ErrorNodeNoCause struct { + pc uintptr // Represents a Program Counter that you can get symbols for. +} + +// Error returns a string with the PC's symbols or "" if the PC is invalid. +// When defining a new error type, have its Error method call this one passing +// it the string representation of the error. +func (e *ErrorNodeNoCause) Error(msg string) string { + return errorWithPC(msg, e.pc) +} + +// Temporary returns true if the error occurred due to a temporary condition. +func (e ErrorNodeNoCause) Temporary() bool { + return false +} + +// Timeout returns true if the error occurred due to time expiring. +func (e ErrorNodeNoCause) Timeout() bool { + return false +} + +// Initialize is used to initialize an embedded ErrorNode field. +// It captures the caller's program counter. +// To initialize the field, use "ErrorNodeNoCause{}.Initialize(3)". A callersToSkip +// value of 3 is very common; but, depending on your code nesting, you may need +// a different value. +func (ErrorNodeNoCause) Initialize(callersToSkip int) ErrorNodeNoCause { + pc := getPC(callersToSkip) + return ErrorNodeNoCause{pc: pc} +} + // NewError creates a simple string error (like Error.New). But, this -// error also captures the caller's Program Counter and the preceding error. +// error also captures the caller's Program Counter and the preceding error (if provided). func NewError(cause error, msg string) error { - return &pcError{ - ErrorNode: ErrorNode{}.Initialize(cause, 3), - msg: msg, + if cause != nil { + return &pcError{ + ErrorNode: ErrorNode{}.Initialize(cause, 3), + msg: msg, + } + } + return &pcErrorNoCause{ + ErrorNodeNoCause: ErrorNodeNoCause{}.Initialize(3), + msg: msg, } } @@ -119,3 +170,12 @@ type pcError struct { // Error satisfies the error interface. It shows the error with Program Counter // symbols and calls Error on the preceding error so you can see the full error chain. func (e *pcError) Error() string { return e.ErrorNode.Error(e.msg) } + +// pcErrorNoCause is a simple string error (like error.New) with an ErrorNode (PC). +type pcErrorNoCause struct { + ErrorNodeNoCause + msg string +} + +// Error satisfies the error interface. It shows the error with Program Counter symbols. +func (e *pcErrorNoCause) Error() string { return e.ErrorNodeNoCause.Error(e.msg) } diff --git a/vendor/github.com/StackExchange/wmi/swbemservices.go b/vendor/github.com/StackExchange/wmi/swbemservices.go index 9765a53f74..3ff8756303 100644 --- a/vendor/github.com/StackExchange/wmi/swbemservices.go +++ b/vendor/github.com/StackExchange/wmi/swbemservices.go @@ -77,7 +77,7 @@ func (s *SWbemServices) process(initError chan error) { //fmt.Println("process: starting background thread initialization") //All OLE/WMI calls must happen on the same initialized thead, so lock this goroutine runtime.LockOSThread() - defer runtime.LockOSThread() + defer runtime.UnlockOSThread() err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED) if err != nil { diff --git a/vendor/github.com/StackExchange/wmi/wmi.go b/vendor/github.com/StackExchange/wmi/wmi.go index a951b1258b..eab18cbfee 100644 --- a/vendor/github.com/StackExchange/wmi/wmi.go +++ b/vendor/github.com/StackExchange/wmi/wmi.go @@ -285,6 +285,10 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat } defer prop.Clear() + if prop.VT == 0x1 { //VT_NULL + continue + } + switch val := prop.Value().(type) { case int8, int16, int32, int64, int: v := reflect.ValueOf(val).Int() @@ -383,7 +387,7 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat } f.Set(fArr) } - case reflect.Uint8: + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: safeArray := prop.ToArray() if safeArray != nil { arr := safeArray.ToValueArray() @@ -394,6 +398,17 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat } f.Set(fArr) } + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + safeArray := prop.ToArray() + if safeArray != nil { + arr := safeArray.ToValueArray() + fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr)) + for i, v := range arr { + s := fArr.Index(i) + s.SetInt(reflect.ValueOf(v).Int()) + } + f.Set(fArr) + } default: return &ErrFieldMismatch{ StructType: of.Type(), diff --git a/vendor/github.com/aristanetworks/goarista/monotime/issue15006.s b/vendor/github.com/aristanetworks/goarista/monotime/issue15006.s index 66109f4f31..0d11d8d6a0 100644 --- a/vendor/github.com/aristanetworks/goarista/monotime/issue15006.s +++ b/vendor/github.com/aristanetworks/goarista/monotime/issue15006.s @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Arista Networks, Inc. +// Copyright (c) 2016 Arista Networks, Inc. // Use of this source code is governed by the Apache License 2.0 // that can be found in the COPYING file. diff --git a/vendor/github.com/aristanetworks/goarista/monotime/nanotime.go b/vendor/github.com/aristanetworks/goarista/monotime/nanotime.go index 5f5fbc7ae5..d999a42b72 100644 --- a/vendor/github.com/aristanetworks/goarista/monotime/nanotime.go +++ b/vendor/github.com/aristanetworks/goarista/monotime/nanotime.go @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Arista Networks, Inc. +// Copyright (c) 2016 Arista Networks, Inc. // Use of this source code is governed by the Apache License 2.0 // that can be found in the COPYING file. diff --git a/vendor/github.com/btcsuite/btcd/btcec/pubkey.go b/vendor/github.com/btcsuite/btcd/btcec/pubkey.go index b74917718f..cf49807522 100644 --- a/vendor/github.com/btcsuite/btcd/btcec/pubkey.go +++ b/vendor/github.com/btcsuite/btcd/btcec/pubkey.go @@ -32,8 +32,9 @@ func decompressPoint(curve *KoblitzCurve, x *big.Int, ybit bool) (*big.Int, erro x3 := new(big.Int).Mul(x, x) x3.Mul(x3, x) x3.Add(x3, curve.Params().B) + x3.Mod(x3, curve.Params().P) - // now calculate sqrt mod p of x2 + B + // Now calculate sqrt mod p of x^3 + B // This code used to do a full sqrt based on tonelli/shanks, // but this was replaced by the algorithms referenced in // https://bitcointalk.org/index.php?topic=162805.msg1712294#msg1712294 @@ -42,9 +43,19 @@ func decompressPoint(curve *KoblitzCurve, x *big.Int, ybit bool) (*big.Int, erro if ybit != isOdd(y) { y.Sub(curve.Params().P, y) } + + // Check that y is a square root of x^3 + B. + y2 := new(big.Int).Mul(y, y) + y2.Mod(y2, curve.Params().P) + if y2.Cmp(x3) != 0 { + return nil, fmt.Errorf("invalid square root") + } + + // Verify that y-coord has expected parity. if ybit != isOdd(y) { return nil, fmt.Errorf("ybit doesn't match oddness") } + return y, nil } diff --git a/vendor/github.com/btcsuite/btcd/btcec/signature.go b/vendor/github.com/btcsuite/btcd/btcec/signature.go index 4392ab41a2..f1c4377499 100644 --- a/vendor/github.com/btcsuite/btcd/btcec/signature.go +++ b/vendor/github.com/btcsuite/btcd/btcec/signature.go @@ -85,6 +85,11 @@ func (sig *Signature) IsEqual(otherSig *Signature) bool { sig.S.Cmp(otherSig.S) == 0 } +// MinSigLen is the minimum length of a DER encoded signature and is when both R +// and S are 1 byte each. +// 0x30 + <1-byte> + 0x02 + 0x01 + + 0x2 + 0x01 + +const MinSigLen = 8 + func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature, error) { // Originally this code used encoding/asn1 in order to parse the // signature, but a number of problems were found with this approach. @@ -98,9 +103,7 @@ func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature, error) signature := &Signature{} - // minimal message is when both numbers are 1 bytes. adding up to: - // 0x30 + len + 0x02 + 0x01 + + 0x2 + 0x01 + - if len(sigStr) < 8 { + if len(sigStr) < MinSigLen { return nil, errors.New("malformed signature: too short") } // 0x30 @@ -112,7 +115,10 @@ func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature, error) // length of remaining message siglen := sigStr[index] index++ - if int(siglen+2) > len(sigStr) { + + // siglen should be less than the entire message and greater than + // the minimal message size. + if int(siglen+2) > len(sigStr) || int(siglen+2) < MinSigLen { return nil, errors.New("malformed signature: bad length") } // trim the slice we're working on so we only look at what matters. @@ -269,7 +275,7 @@ func hashToInt(hash []byte, c elliptic.Curve) *big.Int { return ret } -// recoverKeyFromSignature recoves a public key from the signature "sig" on the +// recoverKeyFromSignature recovers a public key from the signature "sig" on the // given message hash "msg". Based on the algorithm found in section 5.1.5 of // SEC 1 Ver 2.0, page 47-48 (53 and 54 in the pdf). This performs the details // in the inner loop in Step 1. The counter provided is actually the j parameter @@ -421,9 +427,7 @@ func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, error) { k := nonceRFC6979(privkey.D, hash) inv := new(big.Int).ModInverse(k, N) r, _ := privkey.Curve.ScalarBaseMult(k.Bytes()) - if r.Cmp(N) == 1 { - r.Sub(r, N) - } + r.Mod(r, N) if r.Sign() == 0 { return nil, errors.New("calculated R is zero") diff --git a/vendor/github.com/cespare/cp/cp.go b/vendor/github.com/cespare/cp/cp.go index d71dbb4ba2..02bed0d0f0 100644 --- a/vendor/github.com/cespare/cp/cp.go +++ b/vendor/github.com/cespare/cp/cp.go @@ -6,14 +6,28 @@ import ( "io" "os" "path/filepath" - "strings" ) var errCopyFileWithDir = errors.New("dir argument to CopyFile") -// CopyFile copies the file with path src to dst. The new file must not exist. +const ( + flagDefault = os.O_WRONLY | os.O_CREATE | os.O_EXCL + flagOverwrite = os.O_WRONLY | os.O_CREATE | os.O_TRUNC +) + +// CopyFile copies the file at src to dst. The new file must not exist. // It is created with the same permissions as src. func CopyFile(dst, src string) error { + return copyFile(dst, src, flagDefault) +} + +// CopyFileOverwrite is like CopyFile except that it overwrites dst +// if it already exists. +func CopyFileOverwrite(dst, src string) error { + return copyFile(dst, src, flagOverwrite) +} + +func copyFile(dst, src string, flag int) error { rf, err := os.Open(src) if err != nil { return err @@ -27,32 +41,62 @@ func CopyFile(dst, src string) error { return errCopyFileWithDir } - wf, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, rstat.Mode()) + wf, err := os.OpenFile(dst, flag, rstat.Mode()) if err != nil { return err } + defer wf.Close() + if flag&os.O_EXCL == 0 { + // We may be overwriting an existing file. + // Ensure the file mode matches. + stat, err := wf.Stat() + if err != nil { + return err + } + if stat.Mode() != rstat.Mode() { + if err := wf.Chmod(rstat.Mode()); err != nil { + return err + } + } + } if _, err := io.Copy(wf, rf); err != nil { - wf.Close() return err } return wf.Close() } // CopyAll copies the file or (recursively) the directory at src to dst. -// Permissions are preserved. dst must not already exist. +// Permissions are preserved. The target directory must not already exist. func CopyAll(dst, src string) error { - return filepath.Walk(src, makeWalkFn(dst, src)) + return filepath.Walk(src, makeWalkFn(dst, src, flagDefault)) } -func makeWalkFn(dst, src string) filepath.WalkFunc { +// CopyAllOverwrite is like CopyAll except that it recursively overwrites +// any existing directories or files. +func CopyAllOverwrite(dst, src string) error { + return filepath.Walk(src, makeWalkFn(dst, src, flagOverwrite)) +} + +func makeWalkFn(dst, src string, flag int) filepath.WalkFunc { return func(path string, info os.FileInfo, err error) error { if err != nil { return err } - dstPath := filepath.Join(dst, strings.TrimPrefix(path, src)) - if info.IsDir() { - return os.Mkdir(dstPath, info.Mode()) + rel, err := filepath.Rel(src, path) + if err != nil { + // Given the Walk contract, Rel must succeed. + panic("shouldn't happen") } - return CopyFile(dstPath, path) + dstPath := filepath.Join(dst, rel) + if info.IsDir() { + err := os.Mkdir(dstPath, info.Mode()) + // In overwrite mode, allow the directory to already exist + // (but make sure the permissions match). + if os.IsExist(err) && flag&os.O_EXCL == 0 { + return os.Chmod(dstPath, info.Mode()) + } + return err + } + return copyFile(dstPath, path, flag) } } diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE index c836416192..bc52e96f2b 100644 --- a/vendor/github.com/davecgh/go-spew/LICENSE +++ b/vendor/github.com/davecgh/go-spew/LICENSE @@ -2,7 +2,7 @@ ISC License Copyright (c) 2012-2016 Dave Collins -Permission to use, copy, modify, and distribute this software for any +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go index 8a4a6589a2..792994785e 100644 --- a/vendor/github.com/davecgh/go-spew/spew/bypass.go +++ b/vendor/github.com/davecgh/go-spew/spew/bypass.go @@ -16,7 +16,9 @@ // when the code is not running on Google App Engine, compiled by GopherJS, and // "-tags safe" is not added to the go build command line. The "disableunsafe" // tag is deprecated and thus should not be used. -// +build !js,!appengine,!safe,!disableunsafe +// Go versions prior to 1.4 are disabled because they use a different layout +// for interfaces which make the implementation of unsafeReflectValue more complex. +// +build !js,!appengine,!safe,!disableunsafe,go1.4 package spew @@ -34,80 +36,49 @@ const ( ptrSize = unsafe.Sizeof((*byte)(nil)) ) -var ( - // offsetPtr, offsetScalar, and offsetFlag are the offsets for the - // internal reflect.Value fields. These values are valid before golang - // commit ecccf07e7f9d which changed the format. The are also valid - // after commit 82f48826c6c7 which changed the format again to mirror - // the original format. Code in the init function updates these offsets - // as necessary. - offsetPtr = uintptr(ptrSize) - offsetScalar = uintptr(0) - offsetFlag = uintptr(ptrSize * 2) +type flag uintptr - // flagKindWidth and flagKindShift indicate various bits that the - // reflect package uses internally to track kind information. - // - // flagRO indicates whether or not the value field of a reflect.Value is - // read-only. - // - // flagIndir indicates whether the value field of a reflect.Value is - // the actual data or a pointer to the data. - // - // These values are valid before golang commit 90a7c3c86944 which - // changed their positions. Code in the init function updates these - // flags as necessary. - flagKindWidth = uintptr(5) - flagKindShift = uintptr(flagKindWidth - 1) - flagRO = uintptr(1 << 0) - flagIndir = uintptr(1 << 1) +var ( + // flagRO indicates whether the value field of a reflect.Value + // is read-only. + flagRO flag + + // flagAddr indicates whether the address of the reflect.Value's + // value may be taken. + flagAddr flag ) -func init() { - // Older versions of reflect.Value stored small integers directly in the - // ptr field (which is named val in the older versions). Versions - // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named - // scalar for this purpose which unfortunately came before the flag - // field, so the offset of the flag field is different for those - // versions. - // - // This code constructs a new reflect.Value from a known small integer - // and checks if the size of the reflect.Value struct indicates it has - // the scalar field. When it does, the offsets are updated accordingly. - vv := reflect.ValueOf(0xf00) - if unsafe.Sizeof(vv) == (ptrSize * 4) { - offsetScalar = ptrSize * 2 - offsetFlag = ptrSize * 3 - } +// flagKindMask holds the bits that make up the kind +// part of the flags field. In all the supported versions, +// it is in the lower 5 bits. +const flagKindMask = flag(0x1f) - // Commit 90a7c3c86944 changed the flag positions such that the low - // order bits are the kind. This code extracts the kind from the flags - // field and ensures it's the correct type. When it's not, the flag - // order has been changed to the newer format, so the flags are updated - // accordingly. - upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag) - upfv := *(*uintptr)(upf) - flagKindMask := uintptr((1<>flagKindShift != uintptr(reflect.Int) { - flagKindShift = 0 - flagRO = 1 << 5 - flagIndir = 1 << 6 +// Different versions of Go have used different +// bit layouts for the flags type. This table +// records the known combinations. +var okFlags = []struct { + ro, addr flag +}{{ + // From Go 1.4 to 1.5 + ro: 1 << 5, + addr: 1 << 7, +}, { + // Up to Go tip. + ro: 1<<5 | 1<<6, + addr: 1 << 8, +}} - // Commit adf9b30e5594 modified the flags to separate the - // flagRO flag into two bits which specifies whether or not the - // field is embedded. This causes flagIndir to move over a bit - // and means that flagRO is the combination of either of the - // original flagRO bit and the new bit. - // - // This code detects the change by extracting what used to be - // the indirect bit to ensure it's set. When it's not, the flag - // order has been changed to the newer format, so the flags are - // updated accordingly. - if upfv&flagIndir == 0 { - flagRO = 3 << 5 - flagIndir = 1 << 7 - } +var flagValOffset = func() uintptr { + field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") + if !ok { + panic("reflect.Value has no flag field") } + return field.Offset +}() + +// flagField returns a pointer to the flag field of a reflect.Value. +func flagField(v *reflect.Value) *flag { + return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) } // unsafeReflectValue converts the passed reflect.Value into a one that bypasses @@ -119,34 +90,56 @@ func init() { // This allows us to check for implementations of the Stringer and error // interfaces to be used for pretty printing ordinarily unaddressable and // inaccessible values such as unexported struct fields. -func unsafeReflectValue(v reflect.Value) (rv reflect.Value) { - indirects := 1 - vt := v.Type() - upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr) - rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag)) - if rvf&flagIndir != 0 { - vt = reflect.PtrTo(v.Type()) - indirects++ - } else if offsetScalar != 0 { - // The value is in the scalar field when it's not one of the - // reference types. - switch vt.Kind() { - case reflect.Uintptr: - case reflect.Chan: - case reflect.Func: - case reflect.Map: - case reflect.Ptr: - case reflect.UnsafePointer: - default: - upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + - offsetScalar) +func unsafeReflectValue(v reflect.Value) reflect.Value { + if !v.IsValid() || (v.CanInterface() && v.CanAddr()) { + return v + } + flagFieldPtr := flagField(&v) + *flagFieldPtr &^= flagRO + *flagFieldPtr |= flagAddr + return v +} + +// Sanity checks against future reflect package changes +// to the type or semantics of the Value.flag field. +func init() { + field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") + if !ok { + panic("reflect.Value has no flag field") + } + if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { + panic("reflect.Value flag field has changed kind") + } + type t0 int + var t struct { + A t0 + // t0 will have flagEmbedRO set. + t0 + // a will have flagStickyRO set + a t0 + } + vA := reflect.ValueOf(t).FieldByName("A") + va := reflect.ValueOf(t).FieldByName("a") + vt0 := reflect.ValueOf(t).FieldByName("t0") + + // Infer flagRO from the difference between the flags + // for the (otherwise identical) fields in t. + flagPublic := *flagField(&vA) + flagWithRO := *flagField(&va) | *flagField(&vt0) + flagRO = flagPublic ^ flagWithRO + + // Infer flagAddr from the difference between a value + // taken from a pointer and not. + vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A") + flagNoPtr := *flagField(&vA) + flagPtr := *flagField(&vPtrA) + flagAddr = flagNoPtr ^ flagPtr + + // Check that the inferred flags tally with one of the known versions. + for _, f := range okFlags { + if flagRO == f.ro && flagAddr == f.addr { + return } } - - pv := reflect.NewAt(vt, upv) - rv = pv - for i := 0; i < indirects; i++ { - rv = rv.Elem() - } - return rv + panic("reflect.Value read-only flag has changed semantics") } diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go index 1fe3cf3d5d..205c28d68c 100644 --- a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go +++ b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go @@ -16,7 +16,7 @@ // when the code is running on Google App Engine, compiled by GopherJS, or // "-tags safe" is added to the go build command line. The "disableunsafe" // tag is deprecated and thus should not be used. -// +build js appengine safe disableunsafe +// +build js appengine safe disableunsafe !go1.4 package spew diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go index 7c519ff47a..1be8ce9457 100644 --- a/vendor/github.com/davecgh/go-spew/spew/common.go +++ b/vendor/github.com/davecgh/go-spew/spew/common.go @@ -180,7 +180,7 @@ func printComplex(w io.Writer, c complex128, floatPrecision int) { w.Write(closeParenBytes) } -// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x' +// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x' // prefix to Writer w. func printHexPtr(w io.Writer, p uintptr) { // Null pointer. diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go index df1d582a72..f78d89fc1f 100644 --- a/vendor/github.com/davecgh/go-spew/spew/dump.go +++ b/vendor/github.com/davecgh/go-spew/spew/dump.go @@ -35,16 +35,16 @@ var ( // cCharRE is a regular expression that matches a cgo char. // It is used to detect character arrays to hexdump them. - cCharRE = regexp.MustCompile("^.*\\._Ctype_char$") + cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`) // cUnsignedCharRE is a regular expression that matches a cgo unsigned // char. It is used to detect unsigned character arrays to hexdump // them. - cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$") + cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`) // cUint8tCharRE is a regular expression that matches a cgo uint8_t. // It is used to detect uint8_t arrays to hexdump them. - cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$") + cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`) ) // dumpState contains information about the state of a dump operation. @@ -143,10 +143,10 @@ func (d *dumpState) dumpPtr(v reflect.Value) { // Display dereferenced value. d.w.Write(openParenBytes) switch { - case nilFound == true: + case nilFound: d.w.Write(nilAngleBytes) - case cycleFound == true: + case cycleFound: d.w.Write(circularBytes) default: diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go index c49875bacb..b04edb7d7a 100644 --- a/vendor/github.com/davecgh/go-spew/spew/format.go +++ b/vendor/github.com/davecgh/go-spew/spew/format.go @@ -182,10 +182,10 @@ func (f *formatState) formatPtr(v reflect.Value) { // Display dereferenced value. switch { - case nilFound == true: + case nilFound: f.fs.Write(nilAngleBytes) - case cycleFound == true: + case cycleFound: f.fs.Write(circularShortBytes) default: diff --git a/vendor/github.com/deckarep/golang-set/threadsafe.go b/vendor/github.com/deckarep/golang-set/threadsafe.go index 002e06af1f..269b4ab0cb 100644 --- a/vendor/github.com/deckarep/golang-set/threadsafe.go +++ b/vendor/github.com/deckarep/golang-set/threadsafe.go @@ -226,8 +226,14 @@ func (set *threadSafeSet) String() string { func (set *threadSafeSet) PowerSet() Set { set.RLock() - ret := set.s.PowerSet() + unsafePowerSet := set.s.PowerSet().(*threadUnsafeSet) set.RUnlock() + + ret := &threadSafeSet{s: newThreadUnsafeSet()} + for subset := range unsafePowerSet.Iter() { + unsafeSubset := subset.(*threadUnsafeSet) + ret.Add(&threadSafeSet{s: *unsafeSubset}) + } return ret } diff --git a/vendor/github.com/deckarep/golang-set/threadunsafe.go b/vendor/github.com/deckarep/golang-set/threadunsafe.go index 10bdd46f15..927eb23195 100644 --- a/vendor/github.com/deckarep/golang-set/threadunsafe.go +++ b/vendor/github.com/deckarep/golang-set/threadunsafe.go @@ -76,6 +76,9 @@ func (set *threadUnsafeSet) Contains(i ...interface{}) bool { func (set *threadUnsafeSet) IsSubset(other Set) bool { _ = other.(*threadUnsafeSet) + if set.Cardinality() > other.Cardinality() { + return false + } for elem := range *set { if !other.Contains(elem) { return false diff --git a/vendor/github.com/docker/docker/LICENSE b/vendor/github.com/docker/docker/LICENSE index 9c8e20ab85..6d8d58fb67 100644 --- a/vendor/github.com/docker/docker/LICENSE +++ b/vendor/github.com/docker/docker/LICENSE @@ -176,7 +176,7 @@ END OF TERMS AND CONDITIONS - Copyright 2013-2017 Docker, Inc. + Copyright 2013-2018 Docker, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/edsrzf/mmap-go/mmap.go b/vendor/github.com/edsrzf/mmap-go/mmap.go index 7bb4965ed5..29655bd222 100644 --- a/vendor/github.com/edsrzf/mmap-go/mmap.go +++ b/vendor/github.com/edsrzf/mmap-go/mmap.go @@ -54,6 +54,10 @@ func Map(f *os.File, prot, flags int) (MMap, error) { // If length < 0, the entire file will be mapped. // If ANON is set in flags, f is ignored. func MapRegion(f *os.File, length int, prot, flags int, offset int64) (MMap, error) { + if offset%int64(os.Getpagesize()) != 0 { + return nil, errors.New("offset parameter must be a multiple of the system's page size") + } + var fd uintptr if flags&ANON == 0 { fd = uintptr(f.Fd()) @@ -77,25 +81,27 @@ func (m *MMap) header() *reflect.SliceHeader { return (*reflect.SliceHeader)(unsafe.Pointer(m)) } +func (m *MMap) addrLen() (uintptr, uintptr) { + header := m.header() + return header.Data, uintptr(header.Len) +} + // Lock keeps the mapped region in physical memory, ensuring that it will not be // swapped out. func (m MMap) Lock() error { - dh := m.header() - return lock(dh.Data, uintptr(dh.Len)) + return m.lock() } // Unlock reverses the effect of Lock, allowing the mapped region to potentially // be swapped out. // If m is already unlocked, aan error will result. func (m MMap) Unlock() error { - dh := m.header() - return unlock(dh.Data, uintptr(dh.Len)) + return m.unlock() } // Flush synchronizes the mapping's contents to the file's contents on disk. func (m MMap) Flush() error { - dh := m.header() - return flush(dh.Data, uintptr(dh.Len)) + return m.flush() } // Unmap deletes the memory mapped region, flushes any remaining changes, and sets @@ -105,8 +111,7 @@ func (m MMap) Flush() error { // Unmap should only be called on the slice value that was originally returned from // a call to Map. Calling Unmap on a derived slice may cause errors. func (m *MMap) Unmap() error { - dh := m.header() - err := unmap(dh.Data, uintptr(dh.Len)) + err := m.unmap() *m = nil return err } diff --git a/vendor/github.com/edsrzf/mmap-go/mmap_unix.go b/vendor/github.com/edsrzf/mmap-go/mmap_unix.go index 4af98420d5..25b13e51fd 100644 --- a/vendor/github.com/edsrzf/mmap-go/mmap_unix.go +++ b/vendor/github.com/edsrzf/mmap-go/mmap_unix.go @@ -7,61 +7,45 @@ package mmap import ( - "syscall" + "golang.org/x/sys/unix" ) func mmap(len int, inprot, inflags, fd uintptr, off int64) ([]byte, error) { - flags := syscall.MAP_SHARED - prot := syscall.PROT_READ + flags := unix.MAP_SHARED + prot := unix.PROT_READ switch { case inprot© != 0: - prot |= syscall.PROT_WRITE - flags = syscall.MAP_PRIVATE + prot |= unix.PROT_WRITE + flags = unix.MAP_PRIVATE case inprot&RDWR != 0: - prot |= syscall.PROT_WRITE + prot |= unix.PROT_WRITE } if inprot&EXEC != 0 { - prot |= syscall.PROT_EXEC + prot |= unix.PROT_EXEC } if inflags&ANON != 0 { - flags |= syscall.MAP_ANON + flags |= unix.MAP_ANON } - b, err := syscall.Mmap(int(fd), off, len, prot, flags) + b, err := unix.Mmap(int(fd), off, len, prot, flags) if err != nil { return nil, err } return b, nil } -func flush(addr, len uintptr) error { - _, _, errno := syscall.Syscall(_SYS_MSYNC, addr, len, _MS_SYNC) - if errno != 0 { - return syscall.Errno(errno) - } - return nil +func (m MMap) flush() error { + return unix.Msync([]byte(m), unix.MS_SYNC) } -func lock(addr, len uintptr) error { - _, _, errno := syscall.Syscall(syscall.SYS_MLOCK, addr, len, 0) - if errno != 0 { - return syscall.Errno(errno) - } - return nil +func (m MMap) lock() error { + return unix.Mlock([]byte(m)) } -func unlock(addr, len uintptr) error { - _, _, errno := syscall.Syscall(syscall.SYS_MUNLOCK, addr, len, 0) - if errno != 0 { - return syscall.Errno(errno) - } - return nil +func (m MMap) unlock() error { + return unix.Munlock([]byte(m)) } -func unmap(addr, len uintptr) error { - _, _, errno := syscall.Syscall(syscall.SYS_MUNMAP, addr, len, 0) - if errno != 0 { - return syscall.Errno(errno) - } - return nil +func (m MMap) unmap() error { + return unix.Munmap([]byte(m)) } diff --git a/vendor/github.com/edsrzf/mmap-go/mmap_windows.go b/vendor/github.com/edsrzf/mmap-go/mmap_windows.go index c3d2d02d3f..631b3825f9 100644 --- a/vendor/github.com/edsrzf/mmap-go/mmap_windows.go +++ b/vendor/github.com/edsrzf/mmap-go/mmap_windows.go @@ -8,7 +8,8 @@ import ( "errors" "os" "sync" - "syscall" + + "golang.org/x/sys/windows" ) // mmap on Windows is a two-step process. @@ -19,23 +20,33 @@ import ( // not a struct, so it's convenient to manipulate. // We keep this map so that we can get back the original handle from the memory address. + +type addrinfo struct { + file windows.Handle + mapview windows.Handle + writable bool +} + var handleLock sync.Mutex -var handleMap = map[uintptr]syscall.Handle{} +var handleMap = map[uintptr]*addrinfo{} func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) { - flProtect := uint32(syscall.PAGE_READONLY) - dwDesiredAccess := uint32(syscall.FILE_MAP_READ) + flProtect := uint32(windows.PAGE_READONLY) + dwDesiredAccess := uint32(windows.FILE_MAP_READ) + writable := false switch { case prot© != 0: - flProtect = syscall.PAGE_WRITECOPY - dwDesiredAccess = syscall.FILE_MAP_COPY + flProtect = windows.PAGE_WRITECOPY + dwDesiredAccess = windows.FILE_MAP_COPY + writable = true case prot&RDWR != 0: - flProtect = syscall.PAGE_READWRITE - dwDesiredAccess = syscall.FILE_MAP_WRITE + flProtect = windows.PAGE_READWRITE + dwDesiredAccess = windows.FILE_MAP_WRITE + writable = true } if prot&EXEC != 0 { flProtect <<= 4 - dwDesiredAccess |= syscall.FILE_MAP_EXECUTE + dwDesiredAccess |= windows.FILE_MAP_EXECUTE } // The maximum size is the area of the file, starting from 0, @@ -45,7 +56,7 @@ func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) { maxSizeHigh := uint32((off + int64(len)) >> 32) maxSizeLow := uint32((off + int64(len)) & 0xFFFFFFFF) // TODO: Do we need to set some security attributes? It might help portability. - h, errno := syscall.CreateFileMapping(syscall.Handle(hfile), nil, flProtect, maxSizeHigh, maxSizeLow, nil) + h, errno := windows.CreateFileMapping(windows.Handle(hfile), nil, flProtect, maxSizeHigh, maxSizeLow, nil) if h == 0 { return nil, os.NewSyscallError("CreateFileMapping", errno) } @@ -54,12 +65,16 @@ func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) { // is the length the user requested. fileOffsetHigh := uint32(off >> 32) fileOffsetLow := uint32(off & 0xFFFFFFFF) - addr, errno := syscall.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len)) + addr, errno := windows.MapViewOfFile(h, dwDesiredAccess, fileOffsetHigh, fileOffsetLow, uintptr(len)) if addr == 0 { return nil, os.NewSyscallError("MapViewOfFile", errno) } handleLock.Lock() - handleMap[addr] = h + handleMap[addr] = &addrinfo{ + file: windows.Handle(hfile), + mapview: h, + writable: writable, + } handleLock.Unlock() m := MMap{} @@ -71,8 +86,9 @@ func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) { return m, nil } -func flush(addr, len uintptr) error { - errno := syscall.FlushViewOfFile(addr, len) +func (m MMap) flush() error { + addr, len := m.addrLen() + errno := windows.FlushViewOfFile(addr, len) if errno != nil { return os.NewSyscallError("FlushViewOfFile", errno) } @@ -85,22 +101,34 @@ func flush(addr, len uintptr) error { return errors.New("unknown base address") } - errno = syscall.FlushFileBuffers(handle) - return os.NewSyscallError("FlushFileBuffers", errno) + if handle.writable { + if err := windows.FlushFileBuffers(handle.file); err != nil { + return os.NewSyscallError("FlushFileBuffers", err) + } + } + + return nil } -func lock(addr, len uintptr) error { - errno := syscall.VirtualLock(addr, len) +func (m MMap) lock() error { + addr, len := m.addrLen() + errno := windows.VirtualLock(addr, len) return os.NewSyscallError("VirtualLock", errno) } -func unlock(addr, len uintptr) error { - errno := syscall.VirtualUnlock(addr, len) +func (m MMap) unlock() error { + addr, len := m.addrLen() + errno := windows.VirtualUnlock(addr, len) return os.NewSyscallError("VirtualUnlock", errno) } -func unmap(addr, len uintptr) error { - flush(addr, len) +func (m MMap) unmap() error { + err := m.flush() + if err != nil { + return err + } + + addr := m.header().Data // Lock the UnmapViewOfFile along with the handleMap deletion. // As soon as we unmap the view, the OS is free to give the // same addr to another new map. We don't want another goroutine @@ -108,7 +136,7 @@ func unmap(addr, len uintptr) error { // we're trying to remove our old addr/handle pair. handleLock.Lock() defer handleLock.Unlock() - err := syscall.UnmapViewOfFile(addr) + err = windows.UnmapViewOfFile(addr) if err != nil { return err } @@ -120,6 +148,6 @@ func unmap(addr, len uintptr) error { } delete(handleMap, addr) - e := syscall.CloseHandle(syscall.Handle(handle)) + e := windows.CloseHandle(windows.Handle(handle.mapview)) return os.NewSyscallError("CloseHandle", e) } diff --git a/vendor/github.com/edsrzf/mmap-go/msync_netbsd.go b/vendor/github.com/edsrzf/mmap-go/msync_netbsd.go deleted file mode 100644 index a64b003e2d..0000000000 --- a/vendor/github.com/edsrzf/mmap-go/msync_netbsd.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2011 Evan Shaw. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package mmap - -const _SYS_MSYNC = 277 -const _MS_SYNC = 0x04 diff --git a/vendor/github.com/edsrzf/mmap-go/msync_unix.go b/vendor/github.com/edsrzf/mmap-go/msync_unix.go deleted file mode 100644 index 91ee5f40f1..0000000000 --- a/vendor/github.com/edsrzf/mmap-go/msync_unix.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2011 Evan Shaw. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd linux openbsd solaris - -package mmap - -import ( - "syscall" -) - -const _SYS_MSYNC = syscall.SYS_MSYNC -const _MS_SYNC = syscall.MS_SYNC diff --git a/vendor/github.com/elastic/gosigar/CHANGELOG.md b/vendor/github.com/elastic/gosigar/CHANGELOG.md index 45262e7b8d..0ce0fad6f1 100644 --- a/vendor/github.com/elastic/gosigar/CHANGELOG.md +++ b/vendor/github.com/elastic/gosigar/CHANGELOG.md @@ -8,12 +8,34 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed -- Added missing runtime import for FreeBSD. #104 - ### Changed ### Deprecated +## [0.10.3] + +### Fixed +- ProcState.Get() doesn't fail under Windows when it cannot obtain process ownership information. #121 + +## [0.10.2] + +### Fixed +- Fix memory leak when getting process arguments. #119 + +## [0.10.1] + +### Fixed +- Replaced the WMI queries with win32 apis due to high CPU usage. #116 + +## [0.10.0] + +### Added +- List filesystems on Windows that have an access path but not an assigned letter. #112 + +### Fixed +- Added missing runtime import for FreeBSD. #104 +- Handle nil command line in Windows processes. #110 + ## [0.9.0] ### Added diff --git a/vendor/github.com/elastic/gosigar/sigar_freebsd.go b/vendor/github.com/elastic/gosigar/sigar_freebsd.go index 9b2af639b6..51dd84aae2 100644 --- a/vendor/github.com/elastic/gosigar/sigar_freebsd.go +++ b/vendor/github.com/elastic/gosigar/sigar_freebsd.go @@ -111,3 +111,48 @@ func parseCpuStat(self *Cpu, line string) error { self.Idle, _ = strtoull(fields[4]) return nil } + +func (self *Mem) Get() error { + val := C.uint32_t(0) + sc := C.size_t(4) + + name := C.CString("vm.stats.vm.v_page_count") + _, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return err + } + pagecount := uint64(val) + + name = C.CString("vm.stats.vm.v_page_size") + _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return err + } + pagesize := uint64(val) + + name = C.CString("vm.stats.vm.v_free_count") + _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return err + } + self.Free = uint64(val) * pagesize + + name = C.CString("vm.stats.vm.v_inactive_count") + _, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0) + C.free(unsafe.Pointer(name)) + if err != nil { + return err + } + kern := uint64(val) + + self.Total = uint64(pagecount * pagesize) + + self.Used = self.Total - self.Free + self.ActualFree = self.Free + (kern * pagesize) + self.ActualUsed = self.Used - (kern * pagesize) + + return nil +} diff --git a/vendor/github.com/elastic/gosigar/sigar_linux.go b/vendor/github.com/elastic/gosigar/sigar_linux.go index 09f2e30b2f..e04e8a97ee 100644 --- a/vendor/github.com/elastic/gosigar/sigar_linux.go +++ b/vendor/github.com/elastic/gosigar/sigar_linux.go @@ -106,3 +106,28 @@ func parseCpuStat(self *Cpu, line string) error { return nil } + +func (self *Mem) Get() error { + + table, err := parseMeminfo() + if err != nil { + return err + } + + self.Total, _ = table["MemTotal"] + self.Free, _ = table["MemFree"] + buffers, _ := table["Buffers"] + cached, _ := table["Cached"] + + if available, ok := table["MemAvailable"]; ok { + // MemAvailable is in /proc/meminfo (kernel 3.14+) + self.ActualFree = available + } else { + self.ActualFree = self.Free + buffers + cached + } + + self.Used = self.Total - self.Free + self.ActualUsed = self.Total - self.ActualFree + + return nil +} diff --git a/vendor/github.com/elastic/gosigar/sigar_linux_common.go b/vendor/github.com/elastic/gosigar/sigar_linux_common.go index 7ca6497622..e2c5e246d5 100644 --- a/vendor/github.com/elastic/gosigar/sigar_linux_common.go +++ b/vendor/github.com/elastic/gosigar/sigar_linux_common.go @@ -51,31 +51,6 @@ func (self *LoadAverage) Get() error { return nil } -func (self *Mem) Get() error { - - table, err := parseMeminfo() - if err != nil { - return err - } - - self.Total, _ = table["MemTotal"] - self.Free, _ = table["MemFree"] - buffers, _ := table["Buffers"] - cached, _ := table["Cached"] - - if available, ok := table["MemAvailable"]; ok { - // MemAvailable is in /proc/meminfo (kernel 3.14+) - self.ActualFree = available - } else { - self.ActualFree = self.Free + buffers + cached - } - - self.Used = self.Total - self.Free - self.ActualUsed = self.Total - self.ActualFree - - return nil -} - func (self *Swap) Get() error { table, err := parseMeminfo() diff --git a/vendor/github.com/elastic/gosigar/sigar_windows.go b/vendor/github.com/elastic/gosigar/sigar_windows.go index c2b54d8d7f..fc868daf3f 100644 --- a/vendor/github.com/elastic/gosigar/sigar_windows.go +++ b/vendor/github.com/elastic/gosigar/sigar_windows.go @@ -12,26 +12,10 @@ import ( "syscall" "time" - "github.com/StackExchange/wmi" "github.com/elastic/gosigar/sys/windows" "github.com/pkg/errors" ) -// Win32_Process represents a process on the Windows operating system. If -// additional fields are added here (that match the Windows struct) they will -// automatically be populated when calling getWin32Process. -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa394372(v=vs.85).aspx -type Win32_Process struct { - CommandLine string -} - -// Win32_OperatingSystem WMI class represents a Windows-based operating system -// installed on a computer. -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa394239(v=vs.85).aspx -type Win32_OperatingSystem struct { - LastBootUpTime time.Time -} - var ( // version is Windows version of the host OS. version = windows.GetWindowsVersion() @@ -83,11 +67,12 @@ func (self *Uptime) Get() error { bootTimeLock.Lock() defer bootTimeLock.Unlock() if bootTime == nil { - os, err := getWin32OperatingSystem() + uptime, err := windows.GetTickCount64() if err != nil { - return errors.Wrap(err, "failed to get boot time using WMI") + return errors.Wrap(err, "failed to get boot time using win32 api") } - bootTime = &os.LastBootUpTime + var boot = time.Unix(int64(uptime), 0) + bootTime = &boot } self.Length = time.Since(*bootTime).Seconds() @@ -155,9 +140,9 @@ func (self *CpuList) Get() error { } func (self *FileSystemList) Get() error { - drives, err := windows.GetLogicalDriveStrings() + drives, err := windows.GetAccessPaths() if err != nil { - return errors.Wrap(err, "GetLogicalDriveStrings failed") + return errors.Wrap(err, "GetAccessPaths failed") } for _, drive := range drives { @@ -209,10 +194,11 @@ func (self *ProcState) Get(pid int) error { errs = append(errs, errors.Wrap(err, "getParentPid failed")) } - self.Username, err = getProcCredName(pid) - if err != nil { - errs = append(errs, errors.Wrap(err, "getProcCredName failed")) - } + // getProcCredName will often fail when run as a non-admin user. This is + // caused by strict ACL of the process token belonging to other users. + // Instead of failing completely, ignore this error and still return most + // data with an empty Username. + self.Username, _ = getProcCredName(pid) if len(errs) > 0 { errStrs := make([]string, 0, len(errs)) @@ -251,7 +237,7 @@ func getProcStatus(pid int) (RunState, error) { var exitCode uint32 err = syscall.GetExitCodeProcess(handle, &exitCode) if err != nil { - return RunStateUnknown, errors.Wrapf(err, "GetExitCodeProcess failed for pid=%v") + return RunStateUnknown, errors.Wrapf(err, "GetExitCodeProcess failed for pid=%v", pid) } if exitCode == 259 { //still active @@ -289,6 +275,8 @@ func getProcCredName(pid int) (string, error) { if err != nil { return "", errors.Wrapf(err, "OpenProcessToken failed for pid=%v", pid) } + // Close token to prevent handle leaks. + defer token.Close() // Find the token user. tokenUser, err := token.GetTokenUser() @@ -296,12 +284,6 @@ func getProcCredName(pid int) (string, error) { return "", errors.Wrapf(err, "GetTokenInformation failed for pid=%v", pid) } - // Close token to prevent handle leaks. - err = token.Close() - if err != nil { - return "", errors.Wrapf(err, "failed while closing process token handle for pid=%v", pid) - } - // Look up domain account by SID. account, domain, _, err := tokenUser.User.Sid.LookupAccount("") if err != nil { @@ -371,13 +353,28 @@ func (self *ProcArgs) Get(pid int) error { if !version.IsWindowsVistaOrGreater() { return ErrNotImplemented{runtime.GOOS} } - - process, err := getWin32Process(int32(pid)) + handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess|windows.PROCESS_VM_READ, false, uint32(pid)) if err != nil { - return errors.Wrapf(err, "ProcArgs failed for pid=%v", pid) + return errors.Wrapf(err, "OpenProcess failed for pid=%v", pid) + } + defer syscall.CloseHandle(handle) + pbi, err := windows.NtQueryProcessBasicInformation(handle) + if err != nil { + return errors.Wrapf(err, "NtQueryProcessBasicInformation failed for pid=%v", pid) + } + if err != nil { + return nil + } + userProcParams, err := windows.GetUserProcessParams(handle, pbi) + if err != nil { + return nil + } + if argsW, err := windows.ReadProcessUnicodeString(handle, &userProcParams.CommandLine); err == nil { + self.List, err = windows.ByteSliceToStringSlice(argsW) + if err != nil { + return err + } } - - self.List = []string{process.CommandLine} return nil } @@ -394,35 +391,6 @@ func (self *FileSystemUsage) Get(path string) error { return nil } -// getWin32Process gets information about the process with the given process ID. -// It uses a WMI query to get the information from the local system. -func getWin32Process(pid int32) (Win32_Process, error) { - var dst []Win32_Process - query := fmt.Sprintf("WHERE ProcessId = %d", pid) - q := wmi.CreateQuery(&dst, query) - err := wmi.Query(q, &dst) - if err != nil { - return Win32_Process{}, fmt.Errorf("could not get Win32_Process %s: %v", query, err) - } - if len(dst) < 1 { - return Win32_Process{}, fmt.Errorf("could not get Win32_Process %s: Process not found", query) - } - return dst[0], nil -} - -func getWin32OperatingSystem() (Win32_OperatingSystem, error) { - var dst []Win32_OperatingSystem - q := wmi.CreateQuery(&dst, "") - err := wmi.Query(q, &dst) - if err != nil { - return Win32_OperatingSystem{}, errors.Wrap(err, "wmi query for Win32_OperatingSystem failed") - } - if len(dst) != 1 { - return Win32_OperatingSystem{}, errors.New("wmi query for Win32_OperatingSystem failed") - } - return dst[0], nil -} - func (self *Rusage) Get(who int) error { if who != 0 { return ErrNotImplemented{runtime.GOOS} diff --git a/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go b/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go index 88df0febfa..7da8a07135 100644 --- a/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go +++ b/vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go @@ -23,6 +23,10 @@ const ( PROCESS_VM_READ uint32 = 0x0010 ) +// SizeOfRtlUserProcessParameters gives the size +// of the RtlUserProcessParameters struct. +const SizeOfRtlUserProcessParameters = unsafe.Sizeof(RtlUserProcessParameters{}) + // MAX_PATH is the maximum length for a path in Windows. // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx const MAX_PATH = 260 @@ -43,6 +47,26 @@ const ( DRIVE_RAMDISK ) +// UnicodeString is Go's equivalent for the _UNICODE_STRING struct. +type UnicodeString struct { + Size uint16 + MaximumLength uint16 + Buffer uintptr +} + +// RtlUserProcessParameters is Go's equivalent for the +// _RTL_USER_PROCESS_PARAMETERS struct. +// A few undocumented fields are exposed. +type RtlUserProcessParameters struct { + Reserved1 [16]byte + Reserved2 [5]uintptr + CurrentDirectoryPath UnicodeString + CurrentDirectoryHandle uintptr + DllPath UnicodeString + ImagePathName UnicodeString + CommandLine UnicodeString +} + func (dt DriveType) String() string { names := map[DriveType]string{ DRIVE_UNKNOWN: "unknown", @@ -151,25 +175,81 @@ func GetLogicalDriveStrings() ([]string, error) { return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed") } - // Split the uint16 slice at null-terminators. - var startIdx int - var drivesUTF16 [][]uint16 - for i, value := range buffer { - if value == 0 { - drivesUTF16 = append(drivesUTF16, buffer[startIdx:i]) - startIdx = i + 1 + return UTF16SliceToStringSlice(buffer), nil +} + +// GetAccessPaths returns the list of access paths for volumes in the system. +func GetAccessPaths() ([]string, error) { + volumes, err := GetVolumes() + if err != nil { + return nil, errors.Wrap(err, "GetVolumes failed") + } + + var paths []string + for _, volumeName := range volumes { + volumePaths, err := GetVolumePathsForVolume(volumeName) + if err != nil { + return nil, errors.Wrapf(err, "failed to get list of access paths for volume '%s'", volumeName) + } + if len(volumePaths) == 0 { + continue + } + + // Get only the first path + paths = append(paths, volumePaths[0]) + } + + return paths, nil +} + +// GetVolumes returs the list of volumes in the system. +// https://docs.microsoft.com/es-es/windows/desktop/api/fileapi/nf-fileapi-findfirstvolumew +func GetVolumes() ([]string, error) { + buffer := make([]uint16, MAX_PATH+1) + + var volumes []string + + h, err := _FindFirstVolume(&buffer[0], uint32(len(buffer))) + if err != nil { + return nil, errors.Wrap(err, "FindFirstVolumeW failed") + } + defer _FindVolumeClose(h) + + for { + volumes = append(volumes, syscall.UTF16ToString(buffer)) + + err = _FindNextVolume(h, &buffer[0], uint32(len(buffer))) + if err != nil { + if errors.Cause(err) == syscall.ERROR_NO_MORE_FILES { + break + } + return nil, errors.Wrap(err, "FindNextVolumeW failed") } } - // Convert the utf16 slices to strings. - drives := make([]string, 0, len(drivesUTF16)) - for _, driveUTF16 := range drivesUTF16 { - if len(driveUTF16) > 0 { - drives = append(drives, syscall.UTF16ToString(driveUTF16)) - } + return volumes, nil +} + +// GetVolumePathsForVolume returns the list of volume paths for a volume. +// https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-getvolumepathnamesforvolumenamew +func GetVolumePathsForVolume(volumeName string) ([]string, error) { + var length uint32 + err := _GetVolumePathNamesForVolumeName(volumeName, nil, 0, &length) + if errors.Cause(err) != syscall.ERROR_MORE_DATA { + return nil, errors.Wrap(err, "GetVolumePathNamesForVolumeNameW failed to get needed buffer length") + } + if length == 0 { + // Not mounted, no paths, that's ok + return nil, nil } - return drives, nil + buffer := make([]uint16, length*(MAX_PATH+1)) + err = _GetVolumePathNamesForVolumeName(volumeName, &buffer[0], length, &length) + if err != nil { + return nil, errors.Wrap(err, "GetVolumePathNamesForVolumeNameW failed") + } + + return UTF16SliceToStringSlice(buffer), nil } // GlobalMemoryStatusEx retrieves information about the system's current usage @@ -361,10 +441,127 @@ func Process32Next(handle syscall.Handle) (ProcessEntry32, error) { return processEntry32, nil } +// UTF16SliceToStringSlice converts slice of uint16 containing a list of UTF16 +// strings to a slice of strings. +func UTF16SliceToStringSlice(buffer []uint16) []string { + // Split the uint16 slice at null-terminators. + var startIdx int + var stringsUTF16 [][]uint16 + for i, value := range buffer { + if value == 0 { + stringsUTF16 = append(stringsUTF16, buffer[startIdx:i]) + startIdx = i + 1 + } + } + + // Convert the utf16 slices to strings. + result := make([]string, 0, len(stringsUTF16)) + for _, stringUTF16 := range stringsUTF16 { + if len(stringUTF16) > 0 { + result = append(result, syscall.UTF16ToString(stringUTF16)) + } + } + + return result +} + +func GetUserProcessParams(handle syscall.Handle, pbi ProcessBasicInformation) (params RtlUserProcessParameters, err error) { + const is32bitProc = unsafe.Sizeof(uintptr(0)) == 4 + + // Offset of params field within PEB structure. + // This structure is different in 32 and 64 bit. + paramsOffset := 0x20 + if is32bitProc { + paramsOffset = 0x10 + } + + // Read the PEB from the target process memory + pebSize := paramsOffset + 8 + peb := make([]byte, pebSize) + nRead, err := ReadProcessMemory(handle, pbi.PebBaseAddress, peb) + if err != nil { + return params, err + } + if nRead != uintptr(pebSize) { + return params, errors.Errorf("PEB: short read (%d/%d)", nRead, pebSize) + } + + // Get the RTL_USER_PROCESS_PARAMETERS struct pointer from the PEB + paramsAddr := *(*uintptr)(unsafe.Pointer(&peb[paramsOffset])) + + // Read the RTL_USER_PROCESS_PARAMETERS from the target process memory + paramsBuf := make([]byte, SizeOfRtlUserProcessParameters) + nRead, err = ReadProcessMemory(handle, paramsAddr, paramsBuf) + if err != nil { + return params, err + } + if nRead != uintptr(SizeOfRtlUserProcessParameters) { + return params, errors.Errorf("RTL_USER_PROCESS_PARAMETERS: short read (%d/%d)", nRead, SizeOfRtlUserProcessParameters) + } + + params = *(*RtlUserProcessParameters)(unsafe.Pointer(¶msBuf[0])) + return params, nil +} + +func ReadProcessUnicodeString(handle syscall.Handle, s *UnicodeString) ([]byte, error) { + buf := make([]byte, s.Size) + nRead, err := ReadProcessMemory(handle, s.Buffer, buf) + if err != nil { + return nil, err + } + if nRead != uintptr(s.Size) { + return nil, errors.Errorf("unicode string: short read: (%d/%d)", nRead, s.Size) + } + return buf, nil +} + +// Use Windows' CommandLineToArgv API to split an UTF-16 command line string +// into a list of parameters. +func ByteSliceToStringSlice(utf16 []byte) ([]string, error) { + if len(utf16) == 0 { + return nil, nil + } + var numArgs int32 + argsWide, err := syscall.CommandLineToArgv((*uint16)(unsafe.Pointer(&utf16[0])), &numArgs) + if err != nil { + return nil, err + } + + // Free memory allocated for CommandLineToArgvW arguments. + defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(argsWide))) + + args := make([]string, numArgs) + for idx := range args { + args[idx] = syscall.UTF16ToString(argsWide[idx][:]) + } + return args, nil +} + +// ReadProcessMemory reads from another process memory. The Handle needs to have +// the PROCESS_VM_READ right. +// A zero-byte read is a no-op, no error is returned. +func ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, dest []byte) (numRead uintptr, err error) { + n := len(dest) + if n == 0 { + return 0, nil + } + if err = _ReadProcessMemory(handle, baseAddress, uintptr(unsafe.Pointer(&dest[0])), uintptr(n), &numRead); err != nil { + return 0, err + } + return numRead, nil +} + +func GetTickCount64() (uptime uint64, err error) { + if uptime, err = _GetTickCount64(); err != nil { + return 0, err + } + return uptime, nil +} + // Use "GOOS=windows go generate -v -x ." to generate the source. // Add -trace to enable debug prints around syscalls. -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go +//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -systemdll=false -output zsyscall_windows.go syscall_windows.go // Windows API calls //sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx @@ -383,3 +580,9 @@ func Process32Next(handle syscall.Handle) (ProcessEntry32, error) { //sys _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW //sys _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) = advapi32.LookupPrivilegeValueW //sys _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges +//sys _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) = kernel32.FindFirstVolumeW +//sys _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) = kernel32.FindNextVolumeW +//sys _FindVolumeClose(handle syscall.Handle) (err error) = kernel32.FindVolumeClose +//sys _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) = kernel32.GetVolumePathNamesForVolumeNameW +//sys _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) = kernel32.ReadProcessMemory +//sys _GetTickCount64() (uptime uint64, err error) = kernel32.GetTickCount64 diff --git a/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go b/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go index 53fae4e3ba..cd5d9ca32e 100644 --- a/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go +++ b/vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go @@ -1,41 +1,74 @@ -// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT +// Code generated by 'go generate'; DO NOT EDIT. package windows -import "unsafe" -import "syscall" +import ( + "syscall" + "unsafe" +) var _ unsafe.Pointer +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return nil + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + var ( modkernel32 = syscall.NewLazyDLL("kernel32.dll") modpsapi = syscall.NewLazyDLL("psapi.dll") modntdll = syscall.NewLazyDLL("ntdll.dll") modadvapi32 = syscall.NewLazyDLL("advapi32.dll") - procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") - procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") - procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") - procGetProcessImageFileNameW = modpsapi.NewProc("GetProcessImageFileNameW") - procGetSystemTimes = modkernel32.NewProc("GetSystemTimes") - procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") - procEnumProcesses = modpsapi.NewProc("EnumProcesses") - procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW") - procProcess32FirstW = modkernel32.NewProc("Process32FirstW") - procProcess32NextW = modkernel32.NewProc("Process32NextW") - procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") - procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation") - procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess") - procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") - procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") - procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") + procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW") + procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") + procGetProcessImageFileNameW = modpsapi.NewProc("GetProcessImageFileNameW") + procGetSystemTimes = modkernel32.NewProc("GetSystemTimes") + procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW") + procEnumProcesses = modpsapi.NewProc("EnumProcesses") + procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW") + procProcess32FirstW = modkernel32.NewProc("Process32FirstW") + procProcess32NextW = modkernel32.NewProc("Process32NextW") + procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") + procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation") + procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess") + procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") + procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW") + procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW") + procFindVolumeClose = modkernel32.NewProc("FindVolumeClose") + procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW") + procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory") + procGetTickCount64 = modkernel32.NewProc("GetTickCount64") ) func _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) { r1, _, e1 := syscall.Syscall(procGlobalMemoryStatusEx.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0) if r1 == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -48,7 +81,7 @@ func _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint3 length = uint32(r0) if length == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -60,7 +93,7 @@ func _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCo r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(psmemCounters)), uintptr(cb)) if r1 == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -73,7 +106,7 @@ func _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, s length = uint32(r0) if length == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -85,7 +118,7 @@ func _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, u r1, _, e1 := syscall.Syscall(procGetSystemTimes.Addr(), 3, uintptr(unsafe.Pointer(idleTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime))) if r1 == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -98,7 +131,7 @@ func _GetDriveType(rootPathName *uint16) (dt DriveType, err error) { dt = DriveType(r0) if dt == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -110,7 +143,7 @@ func _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(sizeBytes), uintptr(unsafe.Pointer(bytesReturned))) if r1 == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -122,7 +155,7 @@ func _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, tota r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailable)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) if r1 == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -134,7 +167,7 @@ func _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) if r1 == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -146,7 +179,7 @@ func _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) if r1 == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -159,7 +192,7 @@ func _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.H handle = syscall.Handle(r0) if handle == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -172,7 +205,7 @@ func _NtQuerySystemInformation(systemInformationClass uint32, systemInformation ntstatus = uint32(r0) if ntstatus == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -185,7 +218,7 @@ func _NtQueryInformationProcess(processHandle syscall.Handle, processInformation ntstatus = uint32(r0) if ntstatus == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -206,7 +239,7 @@ func __LookupPrivilegeName(systemName *uint16, luid *int64, buffer *uint16, size r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) if r1 == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -232,7 +265,7 @@ func __LookupPrivilegeValue(systemName *uint16, name *uint16, luid *int64) (err r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) if r1 == 0 { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) } else { err = syscall.EINVAL } @@ -251,7 +284,90 @@ func _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, o success = r0 != 0 if true { if e1 != 0 { - err = error(e1) + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(size), 0) + handle = syscall.Handle(r0) + if handle == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) { + r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(volumeName)), uintptr(size)) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _FindVolumeClose(handle syscall.Handle) (err error) { + r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(handle), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(volumeName) + if err != nil { + return + } + return __GetVolumePathNamesForVolumeName(_p0, buffer, bufferSize, length) +} + +func __GetVolumePathNamesForVolumeName(volumeName *uint16, buffer *uint16, bufferSize uint32, length *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferSize), uintptr(unsafe.Pointer(length)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) { + r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(handle), uintptr(baseAddress), uintptr(buffer), uintptr(size), uintptr(unsafe.Pointer(numRead)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func _GetTickCount64() (uptime uint64, err error) { + r0, _, e1 := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0) + uptime = uint64(r0) + if uptime == 0 { + if e1 != 0 { + err = errnoErr(e1) } else { err = syscall.EINVAL } diff --git a/vendor/github.com/fatih/color/README.md b/vendor/github.com/fatih/color/README.md index 25abbca3f8..affe322c1b 100644 --- a/vendor/github.com/fatih/color/README.md +++ b/vendor/github.com/fatih/color/README.md @@ -1,6 +1,12 @@ -# Color [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/color) [![Build Status](http://img.shields.io/travis/fatih/color.svg?style=flat-square)](https://travis-ci.org/fatih/color) +# Archived project. No maintenance. + +This project is not maintained anymore and is archived. Feel free to fork and +make your own changes if needed. For more detail read my blog post: [Taking an indefinite sabbatical from my projects](https://arslan.io/2018/10/09/taking-an-indefinite-sabbatical-from-my-projects/) + +Thanks to everyone for their valuable feedback and contributions. +# Color [![GoDoc](https://godoc.org/github.com/fatih/color?status.svg)](https://godoc.org/github.com/fatih/color) [![Build Status](https://img.shields.io/travis/fatih/color.svg?style=flat-square)](https://travis-ci.org/fatih/color) Color lets you use colorized outputs in terms of [ANSI Escape Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It @@ -8,8 +14,7 @@ has support for Windows too! The API can be used in several ways, pick one that suits you. - -![Color](http://i.imgur.com/c1JI0lA.png) +![Color](https://i.imgur.com/c1JI0lA.png) ## Install @@ -18,6 +23,9 @@ suits you. go get github.com/fatih/color ``` +Note that the `vendor` folder is here for stability. Remove the folder if you +already have the dependencies in your GOPATH. + ## Examples ### Standard colors @@ -127,13 +135,15 @@ defer color.Unset() // Use it in your function fmt.Println("All text will now be bold magenta.") ``` -### Disable color +### Disable/Enable color + +There might be a case where you want to explicitly disable/enable color output. the +`go-isatty` package will automatically disable color output for non-tty output streams +(for example if the output were piped directly to `less`) -There might be a case where you want to disable color output (for example to -pipe the standard output of your app to somewhere else). `Color` has support to -disable colors both globally and for single color definition. For example -suppose you have a CLI app and a `--no-color` bool flag. You can easily disable -the color output with: +`Color` has support to disable/enable colors both globally and for single color +definitions. For example suppose you have a CLI app and a `--no-color` bool flag. You +can easily disable the color output with: ```go diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go index 34cd8e4c8a..91c8e9f062 100644 --- a/vendor/github.com/fatih/color/color.go +++ b/vendor/github.com/fatih/color/color.go @@ -17,12 +17,16 @@ var ( // false or true based on the stdout's file descriptor referring to a terminal // or not. This is a global option and affects all colors. For more control // over each color block use the methods DisableColor() individually. - NoColor = !isatty.IsTerminal(os.Stdout.Fd()) || os.Getenv("TERM") == "dumb" + NoColor = os.Getenv("TERM") == "dumb" || + (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd())) // Output defines the standard output of the print functions. By default // os.Stdout is used. Output = colorable.NewColorableStdout() + // Error defines a color supporting writer for os.Stderr. + Error = colorable.NewColorableStderr() + // colorsCache is used to reduce the count of created Color objects and // allows to reuse already created objects with required Attribute. colorsCache = make(map[Attribute]*Color) @@ -340,7 +344,7 @@ func (c *Color) SprintlnFunc() func(a ...interface{}) string { } } -// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m" +// sequence returns a formatted SGR sequence to be plugged into a "\x1b[...m" // an example output might be: "1;36" -> bold cyan func (c *Color) sequence() string { format := make([]string, len(c.params)) @@ -458,68 +462,142 @@ func colorString(format string, p Attribute, a ...interface{}) string { return c.SprintfFunc()(format, a...) } -// Black is an convenient helper function to print with black foreground. A +// Black is a convenient helper function to print with black foreground. A // newline is appended to format by default. func Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) } -// Red is an convenient helper function to print with red foreground. A +// Red is a convenient helper function to print with red foreground. A // newline is appended to format by default. func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) } -// Green is an convenient helper function to print with green foreground. A +// Green is a convenient helper function to print with green foreground. A // newline is appended to format by default. func Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) } -// Yellow is an convenient helper function to print with yellow foreground. +// Yellow is a convenient helper function to print with yellow foreground. // A newline is appended to format by default. func Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) } -// Blue is an convenient helper function to print with blue foreground. A +// Blue is a convenient helper function to print with blue foreground. A // newline is appended to format by default. func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) } -// Magenta is an convenient helper function to print with magenta foreground. +// Magenta is a convenient helper function to print with magenta foreground. // A newline is appended to format by default. func Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) } -// Cyan is an convenient helper function to print with cyan foreground. A +// Cyan is a convenient helper function to print with cyan foreground. A // newline is appended to format by default. func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) } -// White is an convenient helper function to print with white foreground. A +// White is a convenient helper function to print with white foreground. A // newline is appended to format by default. func White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) } -// BlackString is an convenient helper function to return a string with black +// BlackString is a convenient helper function to return a string with black // foreground. func BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) } -// RedString is an convenient helper function to return a string with red +// RedString is a convenient helper function to return a string with red // foreground. func RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) } -// GreenString is an convenient helper function to return a string with green +// GreenString is a convenient helper function to return a string with green // foreground. func GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) } -// YellowString is an convenient helper function to return a string with yellow +// YellowString is a convenient helper function to return a string with yellow // foreground. func YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) } -// BlueString is an convenient helper function to return a string with blue +// BlueString is a convenient helper function to return a string with blue // foreground. func BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) } -// MagentaString is an convenient helper function to return a string with magenta +// MagentaString is a convenient helper function to return a string with magenta // foreground. func MagentaString(format string, a ...interface{}) string { return colorString(format, FgMagenta, a...) } -// CyanString is an convenient helper function to return a string with cyan +// CyanString is a convenient helper function to return a string with cyan // foreground. func CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) } -// WhiteString is an convenient helper function to return a string with white +// WhiteString is a convenient helper function to return a string with white // foreground. func WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) } + +// HiBlack is a convenient helper function to print with hi-intensity black foreground. A +// newline is appended to format by default. +func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) } + +// HiRed is a convenient helper function to print with hi-intensity red foreground. A +// newline is appended to format by default. +func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) } + +// HiGreen is a convenient helper function to print with hi-intensity green foreground. A +// newline is appended to format by default. +func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) } + +// HiYellow is a convenient helper function to print with hi-intensity yellow foreground. +// A newline is appended to format by default. +func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) } + +// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A +// newline is appended to format by default. +func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) } + +// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground. +// A newline is appended to format by default. +func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) } + +// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A +// newline is appended to format by default. +func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) } + +// HiWhite is a convenient helper function to print with hi-intensity white foreground. A +// newline is appended to format by default. +func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) } + +// HiBlackString is a convenient helper function to return a string with hi-intensity black +// foreground. +func HiBlackString(format string, a ...interface{}) string { + return colorString(format, FgHiBlack, a...) +} + +// HiRedString is a convenient helper function to return a string with hi-intensity red +// foreground. +func HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) } + +// HiGreenString is a convenient helper function to return a string with hi-intensity green +// foreground. +func HiGreenString(format string, a ...interface{}) string { + return colorString(format, FgHiGreen, a...) +} + +// HiYellowString is a convenient helper function to return a string with hi-intensity yellow +// foreground. +func HiYellowString(format string, a ...interface{}) string { + return colorString(format, FgHiYellow, a...) +} + +// HiBlueString is a convenient helper function to return a string with hi-intensity blue +// foreground. +func HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) } + +// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta +// foreground. +func HiMagentaString(format string, a ...interface{}) string { + return colorString(format, FgHiMagenta, a...) +} + +// HiCyanString is a convenient helper function to return a string with hi-intensity cyan +// foreground. +func HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) } + +// HiWhiteString is a convenient helper function to return a string with hi-intensity white +// foreground. +func HiWhiteString(format string, a ...interface{}) string { + return colorString(format, FgHiWhite, a...) +} diff --git a/vendor/github.com/fatih/color/doc.go b/vendor/github.com/fatih/color/doc.go index 1e57812d7c..cf1e96500f 100644 --- a/vendor/github.com/fatih/color/doc.go +++ b/vendor/github.com/fatih/color/doc.go @@ -15,6 +15,11 @@ Use simple and default helper functions with predefined foreground colors: color.Yellow("Yellow color too!") color.Magenta("And many others ..") + // Hi-intensity colors + color.HiGreen("Bright green color.") + color.HiBlack("Bright black means gray..") + color.HiWhite("Shiny white color!") + However there are times where custom color mixes are required. Below are some examples to create custom color objects and use the print functions of each separate color object. @@ -74,7 +79,7 @@ Or create SprintXxx functions to mix strings with other non-colorized strings: info := New(FgWhite, BgGreen).SprintFunc() fmt.Printf("this %s rocks!\n", info("package")) -Windows support is enabled by default. All Print functions works as intended. +Windows support is enabled by default. All Print functions work as intended. However only for color.SprintXXX functions, user should use fmt.FprintXXX and set the output to color.Output: diff --git a/vendor/github.com/fjl/memsize/bitmap.go b/vendor/github.com/fjl/memsize/bitmap.go index 47799ea8d3..c3894a2464 100644 --- a/vendor/github.com/fjl/memsize/bitmap.go +++ b/vendor/github.com/fjl/memsize/bitmap.go @@ -37,7 +37,7 @@ func (b *bitmap) isMarked(addr uintptr) bool { return block.isMarked(baddr) } -// countRange returns the number of set bits in the range (addr,addr+n). +// countRange returns the number of set bits in the range [addr, addr+n]. func (b *bitmap) countRange(addr, n uintptr) uintptr { c := uintptr(0) for end := addr + n; addr < end; { @@ -92,7 +92,7 @@ func (b *bmBlock) isMarked(i uintptr) bool { return (b[i/uintptrBits] & (1 << (i % uintptrBits))) != 0 } -// count returns the number of set bits in the range (start,end). +// count returns the number of set bits in the range [start, end]. func (b *bmBlock) count(start, end uintptr) (count int) { br := b[start/uintptrBits : end/uintptrBits+1] for i, w := range br { diff --git a/vendor/github.com/fjl/memsize/memsize.go b/vendor/github.com/fjl/memsize/memsize.go index 2664e87c46..fcbff1f8c3 100644 --- a/vendor/github.com/fjl/memsize/memsize.go +++ b/vendor/github.com/fjl/memsize/memsize.go @@ -101,8 +101,8 @@ func newContext() *context { return &context{seen: newBitmap(), tc: make(typCache), s: newSizes()} } -// scan walks all objects below v, determining their size. All scan* functions return the -// amount of 'extra' memory (e.g. slice data) that is referenced by the object. +// scan walks all objects below v, determining their size. It returns the size of the +// previously unscanned parts of the object. func (c *context) scan(addr address, v reflect.Value, add bool) (extraSize uintptr) { size := v.Type().Size() var marked uintptr @@ -117,15 +117,17 @@ func (c *context) scan(addr address, v reflect.Value, add bool) (extraSize uintp if c.tc.needScan(v.Type()) { extraSize = c.scanContent(addr, v) } + size -= marked + size += extraSize // fmt.Printf("%v: %v %d (add %v, size %d, marked %d, extra %d)\n", addr, v.Type(), size+extraSize, add, v.Type().Size(), marked, extraSize) if add { - size -= marked - size += extraSize c.s.addValue(v, size) } - return extraSize + return size } +// scanContent and all other scan* functions below return the amount of 'extra' memory +// (e.g. slice data) that is referenced by the object. func (c *context) scanContent(addr address, v reflect.Value) uintptr { switch v.Kind() { case reflect.Array: @@ -225,8 +227,10 @@ func (c *context) scanMap(v reflect.Value) uintptr { extra += c.scan(invalidAddr, k, false) extra += c.scan(invalidAddr, v.MapIndex(k), false) } + } else { + extra = len*typ.Key().Size() + len*typ.Elem().Size() } - return len*typ.Key().Size() + len*typ.Elem().Size() + extra + return extra } func (c *context) scanInterface(v reflect.Value) uintptr { @@ -234,10 +238,9 @@ func (c *context) scanInterface(v reflect.Value) uintptr { if !elem.IsValid() { return 0 // nil interface } - c.scan(invalidAddr, elem, false) - if !c.tc.isPointer(elem.Type()) { - // Account for non-pointer size of the value. - return elem.Type().Size() + extra := c.scan(invalidAddr, elem, false) + if elem.Type().Kind() == reflect.Ptr { + extra -= uintptrBytes } - return 0 + return extra } diff --git a/vendor/github.com/go-ole/go-ole/README.md b/vendor/github.com/go-ole/go-ole/README.md index 0ea9db33c7..7b577558d1 100644 --- a/vendor/github.com/go-ole/go-ole/README.md +++ b/vendor/github.com/go-ole/go-ole/README.md @@ -1,4 +1,4 @@ -#Go OLE +# Go OLE [![Build status](https://ci.appveyor.com/api/projects/status/qr0u2sf7q43us9fj?svg=true)](https://ci.appveyor.com/project/jacobsantos/go-ole-jgs28) [![Build Status](https://travis-ci.org/go-ole/go-ole.svg?branch=master)](https://travis-ci.org/go-ole/go-ole) @@ -35,12 +35,12 @@ AppVeyor is used to build on Windows using the (in-development) test COM server. The tests currently do run and do pass and this should be maintained with commits. -##Versioning +## Versioning Go OLE uses [semantic versioning](http://semver.org) for version numbers, which is similar to the version contract of the Go language. Which means that the major version will always maintain backwards compatibility with minor versions. Minor versions will only add new additions and changes. Fixes will always be in patch. This contract should allow you to upgrade to new minor and patch versions without breakage or modifications to your existing code. Leave a ticket, if there is breakage, so that it could be fixed. -##LICENSE +## LICENSE Under the MIT License: http://mattn.mit-license.org/2013 diff --git a/vendor/github.com/go-ole/go-ole/com.go b/vendor/github.com/go-ole/go-ole/com.go index 75ebbf13f6..6f986b1894 100644 --- a/vendor/github.com/go-ole/go-ole/com.go +++ b/vendor/github.com/go-ole/go-ole/com.go @@ -3,9 +3,7 @@ package ole import ( - "errors" "syscall" - "time" "unicode/utf16" "unsafe" ) @@ -21,6 +19,7 @@ var ( procStringFromCLSID, _ = modole32.FindProc("StringFromCLSID") procStringFromIID, _ = modole32.FindProc("StringFromIID") procIIDFromString, _ = modole32.FindProc("IIDFromString") + procCoGetObject, _ = modole32.FindProc("CoGetObject") procGetUserDefaultLCID, _ = modkernel32.FindProc("GetUserDefaultLCID") procCopyMemory, _ = modkernel32.FindProc("RtlMoveMemory") procVariantInit, _ = modoleaut32.FindProc("VariantInit") @@ -209,6 +208,32 @@ func GetActiveObject(clsid *GUID, iid *GUID) (unk *IUnknown, err error) { return } +type BindOpts struct { + CbStruct uint32 + GrfFlags uint32 + GrfMode uint32 + TickCountDeadline uint32 +} + +// GetObject retrieves pointer to active object. +func GetObject(programID string, bindOpts *BindOpts, iid *GUID) (unk *IUnknown, err error) { + if bindOpts != nil { + bindOpts.CbStruct = uint32(unsafe.Sizeof(BindOpts{})) + } + if iid == nil { + iid = IID_IUnknown + } + hr, _, _ := procCoGetObject.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(programID))), + uintptr(unsafe.Pointer(bindOpts)), + uintptr(unsafe.Pointer(iid)), + uintptr(unsafe.Pointer(&unk))) + if hr != 0 { + err = NewError(hr) + } + return +} + // VariantInit initializes variant. func VariantInit(v *VARIANT) (err error) { hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v))) @@ -317,13 +342,3 @@ func DispatchMessage(msg *Msg) (ret int32) { ret = int32(r0) return } - -// GetVariantDate converts COM Variant Time value to Go time.Time. -func GetVariantDate(value float64) (time.Time, error) { - var st syscall.Systemtime - r, _, _ := procVariantTimeToSystemTime.Call(uintptr(value), uintptr(unsafe.Pointer(&st))) - if r != 0 { - return time.Date(int(st.Year), time.Month(st.Month), int(st.Day), int(st.Hour), int(st.Minute), int(st.Second), int(st.Milliseconds/1000), time.UTC), nil - } - return time.Now(), errors.New("Could not convert to time, passing current time.") -} diff --git a/vendor/github.com/go-ole/go-ole/com_func.go b/vendor/github.com/go-ole/go-ole/com_func.go index 425aad3233..cef539d9dd 100644 --- a/vendor/github.com/go-ole/go-ole/com_func.go +++ b/vendor/github.com/go-ole/go-ole/com_func.go @@ -169,6 +169,6 @@ func DispatchMessage(msg *Msg) int32 { return int32(0) } -func GetVariantDate(value float64) (time.Time, error) { +func GetVariantDate(value uint64) (time.Time, error) { return time.Now(), NewError(E_NOTIMPL) } diff --git a/vendor/github.com/go-ole/go-ole/idispatch_windows.go b/vendor/github.com/go-ole/go-ole/idispatch_windows.go index 020e4f51b0..6ec180b55f 100644 --- a/vendor/github.com/go-ole/go-ole/idispatch_windows.go +++ b/vendor/github.com/go-ole/go-ole/idispatch_windows.go @@ -3,6 +3,7 @@ package ole import ( + "math/big" "syscall" "time" "unsafe" @@ -132,6 +133,8 @@ func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{} vargs[n] = NewVariant(VT_R8, *(*int64)(unsafe.Pointer(&vv))) case *float64: vargs[n] = NewVariant(VT_R8|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*float64))))) + case *big.Int: + vargs[n] = NewVariant(VT_DECIMAL, v.(*big.Int).Int64()) case string: vargs[n] = NewVariant(VT_BSTR, int64(uintptr(unsafe.Pointer(SysAllocStringLen(v.(string)))))) case *string: diff --git a/vendor/github.com/go-ole/go-ole/safearray_func.go b/vendor/github.com/go-ole/go-ole/safearray_func.go index 8ff0baa41d..0dee670ceb 100644 --- a/vendor/github.com/go-ole/go-ole/safearray_func.go +++ b/vendor/github.com/go-ole/go-ole/safearray_func.go @@ -124,12 +124,12 @@ func safeArrayGetElementSize(safearray *SafeArray) (*uint32, error) { } // safeArrayGetElement retrieves element at given index. -func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) error { +func safeArrayGetElement(safearray *SafeArray, index int32, pv unsafe.Pointer) error { return NewError(E_NOTIMPL) } // safeArrayGetElement retrieves element at given index and converts to string. -func safeArrayGetElementString(safearray *SafeArray, index int64) (string, error) { +func safeArrayGetElementString(safearray *SafeArray, index int32) (string, error) { return "", NewError(E_NOTIMPL) } @@ -146,8 +146,8 @@ func safeArrayGetIID(safearray *SafeArray) (*GUID, error) { // multidimensional array. // // AKA: SafeArrayGetLBound in Windows API. -func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int64, error) { - return int64(0), NewError(E_NOTIMPL) +func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int32, error) { + return int32(0), NewError(E_NOTIMPL) } // safeArrayGetUBound returns upper bounds of SafeArray. @@ -156,8 +156,8 @@ func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (int64, error) { // multidimensional array. // // AKA: SafeArrayGetUBound in Windows API. -func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (int64, error) { - return int64(0), NewError(E_NOTIMPL) +func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (int32, error) { + return int32(0), NewError(E_NOTIMPL) } // safeArrayGetVartype returns data type of SafeArray. diff --git a/vendor/github.com/go-ole/go-ole/safearray_windows.go b/vendor/github.com/go-ole/go-ole/safearray_windows.go index b27936e24e..b48a2394d1 100644 --- a/vendor/github.com/go-ole/go-ole/safearray_windows.go +++ b/vendor/github.com/go-ole/go-ole/safearray_windows.go @@ -205,7 +205,7 @@ func safeArrayGetElementSize(safearray *SafeArray) (length *uint32, err error) { } // safeArrayGetElement retrieves element at given index. -func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) error { +func safeArrayGetElement(safearray *SafeArray, index int32, pv unsafe.Pointer) error { return convertHresultToError( procSafeArrayGetElement.Call( uintptr(unsafe.Pointer(safearray)), @@ -214,7 +214,7 @@ func safeArrayGetElement(safearray *SafeArray, index int64, pv unsafe.Pointer) e } // safeArrayGetElementString retrieves element at given index and converts to string. -func safeArrayGetElementString(safearray *SafeArray, index int64) (str string, err error) { +func safeArrayGetElementString(safearray *SafeArray, index int32) (str string, err error) { var element *int16 err = convertHresultToError( procSafeArrayGetElement.Call( @@ -243,7 +243,7 @@ func safeArrayGetIID(safearray *SafeArray) (guid *GUID, err error) { // multidimensional array. // // AKA: SafeArrayGetLBound in Windows API. -func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int64, err error) { +func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int32, err error) { err = convertHresultToError( procSafeArrayGetLBound.Call( uintptr(unsafe.Pointer(safearray)), @@ -258,7 +258,7 @@ func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int6 // multidimensional array. // // AKA: SafeArrayGetUBound in Windows API. -func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int64, err error) { +func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int32, err error) { err = convertHresultToError( procSafeArrayGetUBound.Call( uintptr(unsafe.Pointer(safearray)), diff --git a/vendor/github.com/go-ole/go-ole/safearrayconversion.go b/vendor/github.com/go-ole/go-ole/safearrayconversion.go index ffeb2b97b0..259f488ec7 100644 --- a/vendor/github.com/go-ole/go-ole/safearrayconversion.go +++ b/vendor/github.com/go-ole/go-ole/safearrayconversion.go @@ -14,7 +14,7 @@ func (sac *SafeArrayConversion) ToStringArray() (strings []string) { totalElements, _ := sac.TotalElements(0) strings = make([]string, totalElements) - for i := int64(0); i < totalElements; i++ { + for i := int32(0); i < totalElements; i++ { strings[int32(i)], _ = safeArrayGetElementString(sac.Array, i) } @@ -25,7 +25,7 @@ func (sac *SafeArrayConversion) ToByteArray() (bytes []byte) { totalElements, _ := sac.TotalElements(0) bytes = make([]byte, totalElements) - for i := int64(0); i < totalElements; i++ { + for i := int32(0); i < totalElements; i++ { safeArrayGetElement(sac.Array, i, unsafe.Pointer(&bytes[int32(i)])) } @@ -37,59 +37,59 @@ func (sac *SafeArrayConversion) ToValueArray() (values []interface{}) { values = make([]interface{}, totalElements) vt, _ := safeArrayGetVartype(sac.Array) - for i := 0; i < int(totalElements); i++ { + for i := int32(0); i < totalElements; i++ { switch VT(vt) { case VT_BOOL: var v bool - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_I1: var v int8 - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_I2: var v int16 - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_I4: var v int32 - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_I8: var v int64 - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_UI1: var v uint8 - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_UI2: var v uint16 - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_UI4: var v uint32 - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_UI8: var v uint64 - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_R4: var v float32 - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_R8: var v float64 - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_BSTR: var v string - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v case VT_VARIANT: var v VARIANT - safeArrayGetElement(sac.Array, int64(i), unsafe.Pointer(&v)) + safeArrayGetElement(sac.Array, i, unsafe.Pointer(&v)) values[i] = v.Value() default: // TODO @@ -111,14 +111,14 @@ func (sac *SafeArrayConversion) GetSize() (length *uint32, err error) { return safeArrayGetElementSize(sac.Array) } -func (sac *SafeArrayConversion) TotalElements(index uint32) (totalElements int64, err error) { +func (sac *SafeArrayConversion) TotalElements(index uint32) (totalElements int32, err error) { if index < 1 { index = 1 } // Get array bounds - var LowerBounds int64 - var UpperBounds int64 + var LowerBounds int32 + var UpperBounds int32 LowerBounds, err = safeArrayGetLBound(sac.Array, index) if err != nil { diff --git a/vendor/github.com/go-ole/go-ole/variant.go b/vendor/github.com/go-ole/go-ole/variant.go index 36969725eb..967a23fea9 100644 --- a/vendor/github.com/go-ole/go-ole/variant.go +++ b/vendor/github.com/go-ole/go-ole/variant.go @@ -88,10 +88,10 @@ func (v *VARIANT) Value() interface{} { return v.ToString() case VT_DATE: // VT_DATE type will either return float64 or time.Time. - d := float64(v.Val) + d := uint64(v.Val) date, err := GetVariantDate(d) if err != nil { - return d + return float64(v.Val) } return date case VT_UNKNOWN: diff --git a/vendor/github.com/go-stack/stack/stack.go b/vendor/github.com/go-stack/stack/stack.go index 8033c4013a..ac3b93b14f 100644 --- a/vendor/github.com/go-stack/stack/stack.go +++ b/vendor/github.com/go-stack/stack/stack.go @@ -1,3 +1,5 @@ +// +build go1.7 + // Package stack implements utilities to capture, manipulate, and format call // stacks. It provides a simpler API than package runtime. // @@ -21,29 +23,31 @@ import ( // Call records a single function invocation from a goroutine stack. type Call struct { - fn *runtime.Func - pc uintptr + frame runtime.Frame } // Caller returns a Call from the stack of the current goroutine. The argument // skip is the number of stack frames to ascend, with 0 identifying the // calling function. func Caller(skip int) Call { - var pcs [2]uintptr + // As of Go 1.9 we need room for up to three PC entries. + // + // 0. An entry for the stack frame prior to the target to check for + // special handling needed if that prior entry is runtime.sigpanic. + // 1. A possible second entry to hold metadata about skipped inlined + // functions. If inline functions were not skipped the target frame + // PC will be here. + // 2. A third entry for the target frame PC when the second entry + // is used for skipped inline functions. + var pcs [3]uintptr n := runtime.Callers(skip+1, pcs[:]) + frames := runtime.CallersFrames(pcs[:n]) + frame, _ := frames.Next() + frame, _ = frames.Next() - var c Call - - if n < 2 { - return c + return Call{ + frame: frame, } - - c.pc = pcs[1] - if runtime.FuncForPC(pcs[0]).Name() != "runtime.sigpanic" { - c.pc-- - } - c.fn = runtime.FuncForPC(c.pc) - return c } // String implements fmt.Stinger. It is equivalent to fmt.Sprintf("%v", c). @@ -54,9 +58,10 @@ func (c Call) String() string { // MarshalText implements encoding.TextMarshaler. It formats the Call the same // as fmt.Sprintf("%v", c). func (c Call) MarshalText() ([]byte, error) { - if c.fn == nil { + if c.frame == (runtime.Frame{}) { return nil, ErrNoFunc } + buf := bytes.Buffer{} fmt.Fprint(&buf, c) return buf.Bytes(), nil @@ -71,29 +76,33 @@ var ErrNoFunc = errors.New("no call stack information") // %s source file // %d line number // %n function name +// %k last segment of the package path // %v equivalent to %s:%d // // It accepts the '+' and '#' flags for most of the verbs as follows. // -// %+s path of source file relative to the compile time GOPATH +// %+s path of source file relative to the compile time GOPATH, +// or the module path joined to the path of source file relative +// to module root // %#s full path of source file // %+n import path qualified function name +// %+k full package path // %+v equivalent to %+s:%d // %#v equivalent to %#s:%d func (c Call) Format(s fmt.State, verb rune) { - if c.fn == nil { + if c.frame == (runtime.Frame{}) { fmt.Fprintf(s, "%%!%c(NOFUNC)", verb) return } switch verb { case 's', 'v': - file, line := c.fn.FileLine(c.pc) + file := c.frame.File switch { case s.Flag('#'): // done case s.Flag('+'): - file = file[pkgIndex(file, c.fn.Name()):] + file = pkgFilePath(&c.frame) default: const sep = "/" if i := strings.LastIndex(file, sep); i != -1 { @@ -103,16 +112,31 @@ func (c Call) Format(s fmt.State, verb rune) { io.WriteString(s, file) if verb == 'v' { buf := [7]byte{':'} - s.Write(strconv.AppendInt(buf[:1], int64(line), 10)) + s.Write(strconv.AppendInt(buf[:1], int64(c.frame.Line), 10)) } case 'd': - _, line := c.fn.FileLine(c.pc) buf := [6]byte{} - s.Write(strconv.AppendInt(buf[:0], int64(line), 10)) + s.Write(strconv.AppendInt(buf[:0], int64(c.frame.Line), 10)) + + case 'k': + name := c.frame.Function + const pathSep = "/" + start, end := 0, len(name) + if i := strings.LastIndex(name, pathSep); i != -1 { + start = i + len(pathSep) + } + const pkgSep = "." + if i := strings.Index(name[start:], pkgSep); i != -1 { + end = start + i + } + if s.Flag('+') { + start = 0 + } + io.WriteString(s, name[start:end]) case 'n': - name := c.fn.Name() + name := c.frame.Function if !s.Flag('+') { const pathSep = "/" if i := strings.LastIndex(name, pathSep); i != -1 { @@ -127,35 +151,17 @@ func (c Call) Format(s fmt.State, verb rune) { } } +// Frame returns the call frame infomation for the Call. +func (c Call) Frame() runtime.Frame { + return c.frame +} + // PC returns the program counter for this call frame; multiple frames may // have the same PC value. +// +// Deprecated: Use Call.Frame instead. func (c Call) PC() uintptr { - return c.pc -} - -// name returns the import path qualified name of the function containing the -// call. -func (c Call) name() string { - if c.fn == nil { - return "???" - } - return c.fn.Name() -} - -func (c Call) file() string { - if c.fn == nil { - return "???" - } - file, _ := c.fn.FileLine(c.pc) - return file -} - -func (c Call) line() int { - if c.fn == nil { - return 0 - } - _, line := c.fn.FileLine(c.pc) - return line + return c.frame.PC } // CallStack records a sequence of function invocations from a goroutine @@ -179,9 +185,6 @@ func (cs CallStack) MarshalText() ([]byte, error) { buf := bytes.Buffer{} buf.Write(openBracketBytes) for i, pc := range cs { - if pc.fn == nil { - return nil, ErrNoFunc - } if i > 0 { buf.Write(spaceBytes) } @@ -209,18 +212,18 @@ func (cs CallStack) Format(s fmt.State, verb rune) { // identifying the calling function. func Trace() CallStack { var pcs [512]uintptr - n := runtime.Callers(2, pcs[:]) - cs := make([]Call, n) + n := runtime.Callers(1, pcs[:]) - for i, pc := range pcs[:n] { - pcFix := pc - if i > 0 && cs[i-1].fn.Name() != "runtime.sigpanic" { - pcFix-- - } - cs[i] = Call{ - fn: runtime.FuncForPC(pcFix), - pc: pcFix, - } + frames := runtime.CallersFrames(pcs[:n]) + cs := make(CallStack, 0, n) + + // Skip extra frame retrieved just to make sure the runtime.sigpanic + // special case is handled. + frame, more := frames.Next() + + for more { + frame, more = frames.Next() + cs = append(cs, Call{frame: frame}) } return cs @@ -229,7 +232,7 @@ func Trace() CallStack { // TrimBelow returns a slice of the CallStack with all entries below c // removed. func (cs CallStack) TrimBelow(c Call) CallStack { - for len(cs) > 0 && cs[0].pc != c.pc { + for len(cs) > 0 && cs[0] != c { cs = cs[1:] } return cs @@ -238,7 +241,7 @@ func (cs CallStack) TrimBelow(c Call) CallStack { // TrimAbove returns a slice of the CallStack with all entries above c // removed. func (cs CallStack) TrimAbove(c Call) CallStack { - for len(cs) > 0 && cs[len(cs)-1].pc != c.pc { + for len(cs) > 0 && cs[len(cs)-1] != c { cs = cs[:len(cs)-1] } return cs @@ -284,15 +287,90 @@ func pkgIndex(file, funcName string) int { return i + len(sep) } +// pkgFilePath returns the frame's filepath relative to the compile-time GOPATH, +// or its module path joined to its path relative to the module root. +// +// As of Go 1.11 there is no direct way to know the compile time GOPATH or +// module paths at runtime, but we can piece together the desired information +// from available information. We note that runtime.Frame.Function contains the +// function name qualified by the package path, which includes the module path +// but not the GOPATH. We can extract the package path from that and append the +// last segments of the file path to arrive at the desired package qualified +// file path. For example, given: +// +// GOPATH /home/user +// import path pkg/sub +// frame.File /home/user/src/pkg/sub/file.go +// frame.Function pkg/sub.Type.Method +// Desired return pkg/sub/file.go +// +// It appears that we simply need to trim ".Type.Method" from frame.Function and +// append "/" + path.Base(file). +// +// But there are other wrinkles. Although it is idiomatic to do so, the internal +// name of a package is not required to match the last segment of its import +// path. In addition, the introduction of modules in Go 1.11 allows working +// without a GOPATH. So we also must make these work right: +// +// GOPATH /home/user +// import path pkg/go-sub +// package name sub +// frame.File /home/user/src/pkg/go-sub/file.go +// frame.Function pkg/sub.Type.Method +// Desired return pkg/go-sub/file.go +// +// Module path pkg/v2 +// import path pkg/v2/go-sub +// package name sub +// frame.File /home/user/cloned-pkg/go-sub/file.go +// frame.Function pkg/v2/sub.Type.Method +// Desired return pkg/v2/go-sub/file.go +// +// We can handle all of these situations by using the package path extracted +// from frame.Function up to, but not including, the last segment as the prefix +// and the last two segments of frame.File as the suffix of the returned path. +// This preserves the existing behavior when working in a GOPATH without modules +// and a semantically equivalent behavior when used in module aware project. +func pkgFilePath(frame *runtime.Frame) string { + pre := pkgPrefix(frame.Function) + post := pathSuffix(frame.File) + if pre == "" { + return post + } + return pre + "/" + post +} + +// pkgPrefix returns the import path of the function's package with the final +// segment removed. +func pkgPrefix(funcName string) string { + const pathSep = "/" + end := strings.LastIndex(funcName, pathSep) + if end == -1 { + return "" + } + return funcName[:end] +} + +// pathSuffix returns the last two segments of path. +func pathSuffix(path string) string { + const pathSep = "/" + lastSep := strings.LastIndex(path, pathSep) + if lastSep == -1 { + return path + } + return path[strings.LastIndex(path[:lastSep], pathSep)+1:] +} + var runtimePath string func init() { - var pcs [1]uintptr + var pcs [3]uintptr runtime.Callers(0, pcs[:]) - fn := runtime.FuncForPC(pcs[0]) - file, _ := fn.FileLine(pcs[0]) + frames := runtime.CallersFrames(pcs[:]) + frame, _ := frames.Next() + file := frame.File - idx := pkgIndex(file, fn.Name()) + idx := pkgIndex(frame.File, frame.Function) runtimePath = file[:idx] if runtime.GOOS == "windows" { @@ -301,7 +379,7 @@ func init() { } func inGoroot(c Call) bool { - file := c.file() + file := c.frame.File if len(file) == 0 || file[0] == '?' { return true } diff --git a/vendor/github.com/golang/snappy/snappy.go b/vendor/github.com/golang/snappy/snappy.go index 0cf5e379c4..ece692ea46 100644 --- a/vendor/github.com/golang/snappy/snappy.go +++ b/vendor/github.com/golang/snappy/snappy.go @@ -2,10 +2,21 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package snappy implements the snappy block-based compression format. -// It aims for very high speeds and reasonable compression. +// Package snappy implements the Snappy compression format. It aims for very +// high speeds and reasonable compression. // -// The C++ snappy implementation is at https://github.com/google/snappy +// There are actually two Snappy formats: block and stream. They are related, +// but different: trying to decompress block-compressed data as a Snappy stream +// will fail, and vice versa. The block format is the Decode and Encode +// functions and the stream format is the Reader and Writer types. +// +// The block format, the more common case, is used when the complete size (the +// number of bytes) of the original data is known upfront, at the time +// compression starts. The stream format, also known as the framing format, is +// for when that isn't always true. +// +// The canonical, C++ implementation is at https://github.com/google/snappy and +// it only implements the block format. package snappy // import "github.com/golang/snappy" import ( diff --git a/vendor/github.com/graph-gophers/graphql-go/Gopkg.lock b/vendor/github.com/graph-gophers/graphql-go/Gopkg.lock deleted file mode 100644 index 4574275c5d..0000000000 --- a/vendor/github.com/graph-gophers/graphql-go/Gopkg.lock +++ /dev/null @@ -1,25 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/opentracing/opentracing-go" - packages = [ - ".", - "ext", - "log" - ] - revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38" - version = "v1.0.2" - -[[projects]] - branch = "master" - name = "golang.org/x/net" - packages = ["context"] - revision = "f5dfe339be1d06f81b22525fe34671ee7d2c8904" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "f417062128566756a9360b1c13ada79bdeeb6bab1f53ee9147a3328d95c1653f" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/graph-gophers/graphql-go/Gopkg.toml b/vendor/github.com/graph-gophers/graphql-go/Gopkg.toml deleted file mode 100644 index 62b9367998..0000000000 --- a/vendor/github.com/graph-gophers/graphql-go/Gopkg.toml +++ /dev/null @@ -1,10 +0,0 @@ -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. - -[[constraint]] - name = "github.com/opentracing/opentracing-go" - version = "1.0.2" - -[prune] - go-tests = true - unused-packages = true diff --git a/vendor/github.com/graph-gophers/graphql-go/README.md b/vendor/github.com/graph-gophers/graphql-go/README.md index ef4b4639b5..01038bfa47 100644 --- a/vendor/github.com/graph-gophers/graphql-go/README.md +++ b/vendor/github.com/graph-gophers/graphql-go/README.md @@ -16,6 +16,8 @@ safe for production use. - resolvers are matched to the schema based on method sets (can resolve a GraphQL schema with a Go interface or Go struct). - handles panics in resolvers - parallel execution of resolvers +- subscriptions + - [sample WS transport](https://github.com/graph-gophers/graphql-transport-ws) ## Roadmap @@ -63,7 +65,17 @@ $ curl -XPOST -d '{"query": "{ hello }"}' localhost:8080/query ### Resolvers -A resolver must have one method for each field of the GraphQL type it resolves. The method name has to be [exported](https://golang.org/ref/spec#Exported_identifiers) and match the field's name in a non-case-sensitive way. +A resolver must have one method or field for each field of the GraphQL type it resolves. The method or field name has to be [exported](https://golang.org/ref/spec#Exported_identifiers) and match the schema's field's name in a non-case-sensitive way. +You can use struct fields as resolvers by using `SchemaOpt: UseFieldResolvers()`. For example, +``` +opts := []graphql.SchemaOpt{graphql.UseFieldResolvers()} +schema := graphql.MustParseSchema(s, &query{}, opts...) +``` + +When using `UseFieldResolvers` schema option, a struct field will be used *only* when: +- there is no method for a struct field +- a struct field does not implement an interface method +- a struct field does not have arguments The method has up to two arguments: diff --git a/vendor/github.com/graph-gophers/graphql-go/errors/errors.go b/vendor/github.com/graph-gophers/graphql-go/errors/errors.go index fdfa62024d..8ffe818e66 100644 --- a/vendor/github.com/graph-gophers/graphql-go/errors/errors.go +++ b/vendor/github.com/graph-gophers/graphql-go/errors/errors.go @@ -5,11 +5,12 @@ import ( ) type QueryError struct { - Message string `json:"message"` - Locations []Location `json:"locations,omitempty"` - Path []interface{} `json:"path,omitempty"` - Rule string `json:"-"` - ResolverError error `json:"-"` + Message string `json:"message"` + Locations []Location `json:"locations,omitempty"` + Path []interface{} `json:"path,omitempty"` + Rule string `json:"-"` + ResolverError error `json:"-"` + Extensions map[string]interface{} `json:"extensions,omitempty"` } type Location struct { diff --git a/vendor/github.com/graph-gophers/graphql-go/graphql.go b/vendor/github.com/graph-gophers/graphql-go/graphql.go index 06ffd45997..aaa7ebb1ac 100644 --- a/vendor/github.com/graph-gophers/graphql-go/graphql.go +++ b/vendor/github.com/graph-gophers/graphql-go/graphql.go @@ -2,9 +2,9 @@ package graphql import ( "context" - "fmt" - "encoding/json" + "fmt" + "reflect" "github.com/graph-gophers/graphql-go/errors" "github.com/graph-gophers/graphql-go/internal/common" @@ -34,17 +34,15 @@ func ParseSchema(schemaString string, resolver interface{}, opts ...SchemaOpt) ( opt(s) } - if err := s.schema.Parse(schemaString); err != nil { + if err := s.schema.Parse(schemaString, s.useStringDescriptions); err != nil { return nil, err } - if resolver != nil { - r, err := resolvable.ApplyResolver(s.schema, resolver) - if err != nil { - return nil, err - } - s.res = r + r, err := resolvable.ApplyResolver(s.schema, resolver) + if err != nil { + return nil, err } + s.res = r return s, nil } @@ -63,16 +61,35 @@ type Schema struct { schema *schema.Schema res *resolvable.Schema - maxDepth int - maxParallelism int - tracer trace.Tracer - validationTracer trace.ValidationTracer - logger log.Logger + maxDepth int + maxParallelism int + tracer trace.Tracer + validationTracer trace.ValidationTracer + logger log.Logger + useStringDescriptions bool + disableIntrospection bool } // SchemaOpt is an option to pass to ParseSchema or MustParseSchema. type SchemaOpt func(*Schema) +// UseStringDescriptions enables the usage of double quoted and triple quoted +// strings as descriptions as per the June 2018 spec +// https://facebook.github.io/graphql/June2018/. When this is not enabled, +// comments are parsed as descriptions instead. +func UseStringDescriptions() SchemaOpt { + return func(s *Schema) { + s.useStringDescriptions = true + } +} + +// UseFieldResolvers specifies whether to use struct field resolvers +func UseFieldResolvers() SchemaOpt { + return func(s *Schema) { + s.schema.UseFieldResolvers = true + } +} + // MaxDepth specifies the maximum field nesting depth in a query. The default is 0 which disables max depth checking. func MaxDepth(n int) SchemaOpt { return func(s *Schema) { @@ -108,6 +125,13 @@ func Logger(logger log.Logger) SchemaOpt { } } +// DisableIntrospection disables introspection queries. +func DisableIntrospection() SchemaOpt { + return func(s *Schema) { + s.disableIntrospection = true + } +} + // Response represents a typical response of a GraphQL server. It may be encoded to JSON directly or // it may be further processed to a custom response type, for example to include custom error data. // Errors are intentionally serialized first based on the advice in https://github.com/facebook/graphql/commit/7b40390d48680b15cb93e02d46ac5eb249689876#diff-757cea6edf0288677a9eea4cfc801d87R107 @@ -124,14 +148,14 @@ func (s *Schema) Validate(queryString string) []*errors.QueryError { return []*errors.QueryError{qErr} } - return validation.Validate(s.schema, doc, s.maxDepth) + return validation.Validate(s.schema, doc, nil, s.maxDepth) } // Exec executes the given query with the schema's resolver. It panics if the schema was created // without a resolver. If the context get cancelled, no further resolvers will be called and a // the context error will be returned as soon as possible (not immediately). func (s *Schema) Exec(ctx context.Context, queryString string, operationName string, variables map[string]interface{}) *Response { - if s.res == nil { + if s.res.Resolver == (reflect.Value{}) { panic("schema created without resolver, can not exec") } return s.exec(ctx, queryString, operationName, variables, s.res) @@ -144,7 +168,7 @@ func (s *Schema) exec(ctx context.Context, queryString string, operationName str } validationFinish := s.validationTracer.TraceValidation() - errs := validation.Validate(s.schema, doc, s.maxDepth) + errs := validation.Validate(s.schema, doc, variables, s.maxDepth) validationFinish(errs) if len(errs) != 0 { return &Response{Errors: errs} @@ -155,11 +179,22 @@ func (s *Schema) exec(ctx context.Context, queryString string, operationName str return &Response{Errors: []*errors.QueryError{errors.Errorf("%s", err)}} } + // Fill in variables with the defaults from the operation + if variables == nil { + variables = make(map[string]interface{}, len(op.Vars)) + } + for _, v := range op.Vars { + if _, ok := variables[v.Name.Name]; !ok && v.Default != nil { + variables[v.Name.Name] = v.Default.Value(nil) + } + } + r := &exec.Request{ Request: selected.Request{ - Doc: doc, - Vars: variables, - Schema: s.schema, + Doc: doc, + Vars: variables, + Schema: s.schema, + DisableIntrospection: s.disableIntrospection, }, Limiter: make(chan struct{}, s.maxParallelism), Tracer: s.tracer, diff --git a/vendor/github.com/graph-gophers/graphql-go/internal/common/lexer.go b/vendor/github.com/graph-gophers/graphql-go/internal/common/lexer.go index a38fcbaf70..9cc7e5473b 100644 --- a/vendor/github.com/graph-gophers/graphql-go/internal/common/lexer.go +++ b/vendor/github.com/graph-gophers/graphql-go/internal/common/lexer.go @@ -1,7 +1,9 @@ package common import ( + "bytes" "fmt" + "strconv" "strings" "text/scanner" @@ -11,9 +13,10 @@ import ( type syntaxError string type Lexer struct { - sc *scanner.Scanner - next rune - descComment string + sc *scanner.Scanner + next rune + comment bytes.Buffer + useStringDescriptions bool } type Ident struct { @@ -21,13 +24,13 @@ type Ident struct { Loc errors.Location } -func NewLexer(s string) *Lexer { +func NewLexer(s string, useStringDescriptions bool) *Lexer { sc := &scanner.Scanner{ Mode: scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanStrings, } sc.Init(strings.NewReader(s)) - return &Lexer{sc: sc} + return &Lexer{sc: sc, useStringDescriptions: useStringDescriptions} } func (l *Lexer) CatchSyntaxError(f func()) (errRes *errors.QueryError) { @@ -50,13 +53,13 @@ func (l *Lexer) Peek() rune { return l.next } -// Consume whitespace and tokens equivalent to whitespace (e.g. commas and comments). +// ConsumeWhitespace consumes whitespace and tokens equivalent to whitespace (e.g. commas and comments). // // Consumed comment characters will build the description for the next type or field encountered. -// The description is available from `DescComment()`, and will be reset every time `Consume()` is -// executed. -func (l *Lexer) Consume() { - l.descComment = "" +// The description is available from `DescComment()`, and will be reset every time `ConsumeWhitespace()` is +// executed unless l.useStringDescriptions is set. +func (l *Lexer) ConsumeWhitespace() { + l.comment.Reset() for { l.next = l.sc.Scan() @@ -75,7 +78,6 @@ func (l *Lexer) Consume() { // A comment can contain any Unicode code point except `LineTerminator` so a comment always // consists of all code points starting with the '#' character up to but not including the // line terminator. - l.consumeComment() continue } @@ -84,6 +86,29 @@ func (l *Lexer) Consume() { } } +// consumeDescription optionally consumes a description based on the June 2018 graphql spec if any are present. +// +// Single quote strings are also single line. Triple quote strings can be multi-line. Triple quote strings +// whitespace trimmed on both ends. +// If a description is found, consume any following comments as well +// +// http://facebook.github.io/graphql/June2018/#sec-Descriptions +func (l *Lexer) consumeDescription() string { + // If the next token is not a string, we don't consume it + if l.next != scanner.String { + return "" + } + // Triple quote string is an empty "string" followed by an open quote due to the way the parser treats strings as one token + var desc string + if l.sc.Peek() == '"' { + desc = l.consumeTripleQuoteComment() + } else { + desc = l.consumeStringComment() + } + l.ConsumeWhitespace() + return desc +} + func (l *Lexer) ConsumeIdent() string { name := l.sc.TokenText() l.ConsumeToken(scanner.Ident) @@ -101,12 +126,12 @@ func (l *Lexer) ConsumeKeyword(keyword string) { if l.next != scanner.Ident || l.sc.TokenText() != keyword { l.SyntaxError(fmt.Sprintf("unexpected %q, expecting %q", l.sc.TokenText(), keyword)) } - l.Consume() + l.ConsumeWhitespace() } func (l *Lexer) ConsumeLiteral() *BasicLit { lit := &BasicLit{Type: l.next, Text: l.sc.TokenText()} - l.Consume() + l.ConsumeWhitespace() return lit } @@ -114,11 +139,16 @@ func (l *Lexer) ConsumeToken(expected rune) { if l.next != expected { l.SyntaxError(fmt.Sprintf("unexpected %q, expecting %s", l.sc.TokenText(), scanner.TokenString(expected))) } - l.Consume() + l.ConsumeWhitespace() } func (l *Lexer) DescComment() string { - return l.descComment + comment := l.comment.String() + desc := l.consumeDescription() + if l.useStringDescriptions { + return desc + } + return comment } func (l *Lexer) SyntaxError(message string) { @@ -132,11 +162,45 @@ func (l *Lexer) Location() errors.Location { } } +func (l *Lexer) consumeTripleQuoteComment() string { + l.next = l.sc.Next() + if l.next != '"' { + panic("consumeTripleQuoteComment used in wrong context: no third quote?") + } + + var buf bytes.Buffer + var numQuotes int + for { + l.next = l.sc.Next() + if l.next == '"' { + numQuotes++ + } else { + numQuotes = 0 + } + buf.WriteRune(l.next) + if numQuotes == 3 || l.next == scanner.EOF { + break + } + } + val := buf.String() + val = val[:len(val)-numQuotes] + val = strings.TrimSpace(val) + return val +} + +func (l *Lexer) consumeStringComment() string { + val, err := strconv.Unquote(l.sc.TokenText()) + if err != nil { + panic(err) + } + return val +} + // consumeComment consumes all characters from `#` to the first encountered line terminator. -// The characters are appended to `l.descComment`. +// The characters are appended to `l.comment`. func (l *Lexer) consumeComment() { if l.next != '#' { - return + panic("consumeComment used in wrong context") } // TODO: count and trim whitespace so we can dedent any following lines. @@ -144,9 +208,8 @@ func (l *Lexer) consumeComment() { l.sc.Next() } - if l.descComment != "" { - // TODO: use a bytes.Buffer or strings.Builder instead of this. - l.descComment += "\n" + if l.comment.Len() > 0 { + l.comment.WriteRune('\n') } for { @@ -154,8 +217,6 @@ func (l *Lexer) consumeComment() { if next == '\r' || next == '\n' || next == scanner.EOF { break } - - // TODO: use a bytes.Buffer or strings.Build instead of this. - l.descComment += string(next) + l.comment.WriteRune(next) } } diff --git a/vendor/github.com/graph-gophers/graphql-go/internal/exec/exec.go b/vendor/github.com/graph-gophers/graphql-go/internal/exec/exec.go index e6cca7448d..46d6510a9e 100644 --- a/vendor/github.com/graph-gophers/graphql-go/internal/exec/exec.go +++ b/vendor/github.com/graph-gophers/graphql-go/internal/exec/exec.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "fmt" "reflect" "sync" @@ -31,6 +32,10 @@ func (r *Request) handlePanic(ctx context.Context) { } } +type extensionser interface { + Extensions() map[string]interface{} +} + func makePanicError(value interface{}) *errors.QueryError { return errors.Errorf("graphql: panic occurred: %v", value) } @@ -40,7 +45,7 @@ func (r *Request) Execute(ctx context.Context, s *resolvable.Schema, op *query.O func() { defer r.handlePanic(ctx) sels := selected.ApplyOperation(&r.Request, s, op) - r.execSelections(ctx, sels, nil, s.Resolver, &out, op.Type == query.Mutation) + r.execSelections(ctx, sels, nil, s, s.Resolver, &out, op.Type == query.Mutation) }() if err := ctx.Err(); err != nil { @@ -57,11 +62,15 @@ type fieldToExec struct { out *bytes.Buffer } -func (r *Request) execSelections(ctx context.Context, sels []selected.Selection, path *pathSegment, resolver reflect.Value, out *bytes.Buffer, serially bool) { +func resolvedToNull(b *bytes.Buffer) bool { + return bytes.Equal(b.Bytes(), []byte("null")) +} + +func (r *Request) execSelections(ctx context.Context, sels []selected.Selection, path *pathSegment, s *resolvable.Schema, resolver reflect.Value, out *bytes.Buffer, serially bool) { async := !serially && selected.HasAsyncSel(sels) var fields []*fieldToExec - collectFieldsToResolve(sels, resolver, &fields, make(map[string]*fieldToExec)) + collectFieldsToResolve(sels, s, resolver, &fields, make(map[string]*fieldToExec)) if async { var wg sync.WaitGroup @@ -71,14 +80,28 @@ func (r *Request) execSelections(ctx context.Context, sels []selected.Selection, defer wg.Done() defer r.handlePanic(ctx) f.out = new(bytes.Buffer) - execFieldSelection(ctx, r, f, &pathSegment{path, f.field.Alias}, true) + execFieldSelection(ctx, r, s, f, &pathSegment{path, f.field.Alias}, true) }(f) } wg.Wait() + } else { + for _, f := range fields { + f.out = new(bytes.Buffer) + execFieldSelection(ctx, r, s, f, &pathSegment{path, f.field.Alias}, true) + } } out.WriteByte('{') for i, f := range fields { + // If a non-nullable child resolved to null, an error was added to the + // "errors" list in the response, so this field resolves to null. + // If this field is non-nullable, the error is propagated to its parent. + if _, ok := f.field.Type.(*common.NonNull); ok && resolvedToNull(f.out) { + out.Reset() + out.Write([]byte("null")) + return + } + if i > 0 { out.WriteByte(',') } @@ -86,17 +109,12 @@ func (r *Request) execSelections(ctx context.Context, sels []selected.Selection, out.WriteString(f.field.Alias) out.WriteByte('"') out.WriteByte(':') - if async { - out.Write(f.out.Bytes()) - continue - } - f.out = out - execFieldSelection(ctx, r, f, &pathSegment{path, f.field.Alias}, false) + out.Write(f.out.Bytes()) } out.WriteByte('}') } -func collectFieldsToResolve(sels []selected.Selection, resolver reflect.Value, fields *[]*fieldToExec, fieldByAlias map[string]*fieldToExec) { +func collectFieldsToResolve(sels []selected.Selection, s *resolvable.Schema, resolver reflect.Value, fields *[]*fieldToExec, fieldByAlias map[string]*fieldToExec) { for _, sel := range sels { switch sel := sel.(type) { case *selected.SchemaField: @@ -110,7 +128,7 @@ func collectFieldsToResolve(sels []selected.Selection, resolver reflect.Value, f case *selected.TypenameField: sf := &selected.SchemaField{ - Field: resolvable.MetaFieldTypename, + Field: s.Meta.FieldTypename, Alias: sel.Alias, FixedResult: reflect.ValueOf(typeOf(sel, resolver)), } @@ -121,7 +139,7 @@ func collectFieldsToResolve(sels []selected.Selection, resolver reflect.Value, f if !out[1].Bool() { continue } - collectFieldsToResolve(sel.Sels, out[0], fields, fieldByAlias) + collectFieldsToResolve(sel.Sels, s, out[0], fields, fieldByAlias) default: panic("unreachable") @@ -142,7 +160,7 @@ func typeOf(tf *selected.TypenameField, resolver reflect.Value) string { return "" } -func execFieldSelection(ctx context.Context, r *Request, f *fieldToExec, path *pathSegment, applyLimiter bool) { +func execFieldSelection(ctx context.Context, r *Request, s *resolvable.Schema, f *fieldToExec, path *pathSegment, applyLimiter bool) { if applyLimiter { r.Limiter <- struct{}{} } @@ -173,21 +191,33 @@ func execFieldSelection(ctx context.Context, r *Request, f *fieldToExec, path *p return errors.Errorf("%s", err) // don't execute any more resolvers if context got cancelled } - var in []reflect.Value - if f.field.HasContext { - in = append(in, reflect.ValueOf(traceCtx)) - } - if f.field.ArgsPacker != nil { - in = append(in, f.field.PackedArgs) - } - callOut := f.resolver.Method(f.field.MethodIndex).Call(in) - result = callOut[0] - if f.field.HasError && !callOut[1].IsNil() { - resolverErr := callOut[1].Interface().(error) - err := errors.Errorf("%s", resolverErr) - err.Path = path.toSlice() - err.ResolverError = resolverErr - return err + res := f.resolver + if f.field.UseMethodResolver() { + var in []reflect.Value + if f.field.HasContext { + in = append(in, reflect.ValueOf(traceCtx)) + } + if f.field.ArgsPacker != nil { + in = append(in, f.field.PackedArgs) + } + callOut := res.Method(f.field.MethodIndex).Call(in) + result = callOut[0] + if f.field.HasError && !callOut[1].IsNil() { + resolverErr := callOut[1].Interface().(error) + err := errors.Errorf("%s", resolverErr) + err.Path = path.toSlice() + err.ResolverError = resolverErr + if ex, ok := callOut[1].Interface().(extensionser); ok { + err.Extensions = ex.Extensions() + } + return err + } + } else { + // TODO extract out unwrapping ptr logic to a common place + if res.Kind() == reflect.Ptr { + res = res.Elem() + } + result = res.Field(f.field.FieldIndex) } return nil }() @@ -197,28 +227,35 @@ func execFieldSelection(ctx context.Context, r *Request, f *fieldToExec, path *p } if err != nil { + // If an error occurred while resolving a field, it should be treated as though the field + // returned null, and an error must be added to the "errors" list in the response. r.AddError(err) - f.out.WriteString("null") // TODO handle non-nil + f.out.WriteString("null") return } - r.execSelectionSet(traceCtx, f.sels, f.field.Type, path, result, f.out) + r.execSelectionSet(traceCtx, f.sels, f.field.Type, path, s, result, f.out) } -func (r *Request) execSelectionSet(ctx context.Context, sels []selected.Selection, typ common.Type, path *pathSegment, resolver reflect.Value, out *bytes.Buffer) { +func (r *Request) execSelectionSet(ctx context.Context, sels []selected.Selection, typ common.Type, path *pathSegment, s *resolvable.Schema, resolver reflect.Value, out *bytes.Buffer) { t, nonNull := unwrapNonNull(typ) switch t := t.(type) { case *schema.Object, *schema.Interface, *schema.Union: // a reflect.Value of a nil interface will show up as an Invalid value if resolver.Kind() == reflect.Invalid || ((resolver.Kind() == reflect.Ptr || resolver.Kind() == reflect.Interface) && resolver.IsNil()) { + // If a field of a non-null type resolves to null (either because the + // function to resolve the field returned null or because an error occurred), + // add an error to the "errors" list in the response. if nonNull { - panic(errors.Errorf("got nil for non-null %q", t)) + err := errors.Errorf("graphql: got nil for non-null %q", t) + err.Path = path.toSlice() + r.AddError(err) } out.WriteString("null") return } - r.execSelections(ctx, sels, path, resolver, out, false) + r.execSelections(ctx, sels, path, s, resolver, out, false) return } @@ -232,40 +269,7 @@ func (r *Request) execSelectionSet(ctx context.Context, sels []selected.Selectio switch t := t.(type) { case *common.List: - l := resolver.Len() - - if selected.HasAsyncSel(sels) { - var wg sync.WaitGroup - wg.Add(l) - entryouts := make([]bytes.Buffer, l) - for i := 0; i < l; i++ { - go func(i int) { - defer wg.Done() - defer r.handlePanic(ctx) - r.execSelectionSet(ctx, sels, t.OfType, &pathSegment{path, i}, resolver.Index(i), &entryouts[i]) - }(i) - } - wg.Wait() - - out.WriteByte('[') - for i, entryout := range entryouts { - if i > 0 { - out.WriteByte(',') - } - out.Write(entryout.Bytes()) - } - out.WriteByte(']') - return - } - - out.WriteByte('[') - for i := 0; i < l; i++ { - if i > 0 { - out.WriteByte(',') - } - r.execSelectionSet(ctx, sels, t.OfType, &pathSegment{path, i}, resolver.Index(i), out) - } - out.WriteByte(']') + r.execList(ctx, sels, t, path, s, resolver, out) case *schema.Scalar: v := resolver.Interface() @@ -276,8 +280,27 @@ func (r *Request) execSelectionSet(ctx context.Context, sels []selected.Selectio out.Write(data) case *schema.Enum: + var stringer fmt.Stringer = resolver + if s, ok := resolver.Interface().(fmt.Stringer); ok { + stringer = s + } + name := stringer.String() + var valid bool + for _, v := range t.Values { + if v.Name == name { + valid = true + break + } + } + if !valid { + err := errors.Errorf("Invalid value %s.\nExpected type %s, found %s.", name, t.Name, name) + err.Path = path.toSlice() + r.AddError(err) + out.WriteString("null") + return + } out.WriteByte('"') - out.WriteString(resolver.String()) + out.WriteString(name) out.WriteByte('"') default: @@ -285,6 +308,47 @@ func (r *Request) execSelectionSet(ctx context.Context, sels []selected.Selectio } } +func (r *Request) execList(ctx context.Context, sels []selected.Selection, typ *common.List, path *pathSegment, s *resolvable.Schema, resolver reflect.Value, out *bytes.Buffer) { + l := resolver.Len() + entryouts := make([]bytes.Buffer, l) + + if selected.HasAsyncSel(sels) { + var wg sync.WaitGroup + wg.Add(l) + for i := 0; i < l; i++ { + go func(i int) { + defer wg.Done() + defer r.handlePanic(ctx) + r.execSelectionSet(ctx, sels, typ.OfType, &pathSegment{path, i}, s, resolver.Index(i), &entryouts[i]) + }(i) + } + wg.Wait() + } else { + for i := 0; i < l; i++ { + r.execSelectionSet(ctx, sels, typ.OfType, &pathSegment{path, i}, s, resolver.Index(i), &entryouts[i]) + } + } + + _, listOfNonNull := typ.OfType.(*common.NonNull) + + out.WriteByte('[') + for i, entryout := range entryouts { + // If the list wraps a non-null type and one of the list elements + // resolves to null, then the entire list resolves to null. + if listOfNonNull && resolvedToNull(&entryout) { + out.Reset() + out.WriteString("null") + return + } + + if i > 0 { + out.WriteByte(',') + } + out.Write(entryout.Bytes()) + } + out.WriteByte(']') +} + func unwrapNonNull(t common.Type) (common.Type, bool) { if nn, ok := t.(*common.NonNull); ok { return nn.OfType, true diff --git a/vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/meta.go b/vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/meta.go index 826c823484..e9707516ea 100644 --- a/vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/meta.go +++ b/vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/meta.go @@ -9,21 +9,27 @@ import ( "github.com/graph-gophers/graphql-go/introspection" ) -var MetaSchema *Object -var MetaType *Object +// Meta defines the details of the metadata schema for introspection. +type Meta struct { + FieldSchema Field + FieldType Field + FieldTypename Field + Schema *Object + Type *Object +} -func init() { +func newMeta(s *schema.Schema) *Meta { var err error - b := newBuilder(schema.Meta) + b := newBuilder(s) - metaSchema := schema.Meta.Types["__Schema"].(*schema.Object) - MetaSchema, err = b.makeObjectExec(metaSchema.Name, metaSchema.Fields, nil, false, reflect.TypeOf(&introspection.Schema{})) + metaSchema := s.Types["__Schema"].(*schema.Object) + so, err := b.makeObjectExec(metaSchema.Name, metaSchema.Fields, nil, false, reflect.TypeOf(&introspection.Schema{})) if err != nil { panic(err) } - metaType := schema.Meta.Types["__Type"].(*schema.Object) - MetaType, err = b.makeObjectExec(metaType.Name, metaType.Fields, nil, false, reflect.TypeOf(&introspection.Type{})) + metaType := s.Types["__Type"].(*schema.Object) + t, err := b.makeObjectExec(metaType.Name, metaType.Fields, nil, false, reflect.TypeOf(&introspection.Type{})) if err != nil { panic(err) } @@ -31,28 +37,36 @@ func init() { if err := b.finish(); err != nil { panic(err) } -} -var MetaFieldTypename = Field{ - Field: schema.Field{ - Name: "__typename", - Type: &common.NonNull{OfType: schema.Meta.Types["String"]}, - }, - TraceLabel: fmt.Sprintf("GraphQL field: __typename"), -} + fieldTypename := Field{ + Field: schema.Field{ + Name: "__typename", + Type: &common.NonNull{OfType: s.Types["String"]}, + }, + TraceLabel: fmt.Sprintf("GraphQL field: __typename"), + } -var MetaFieldSchema = Field{ - Field: schema.Field{ - Name: "__schema", - Type: schema.Meta.Types["__Schema"], - }, - TraceLabel: fmt.Sprintf("GraphQL field: __schema"), -} + fieldSchema := Field{ + Field: schema.Field{ + Name: "__schema", + Type: s.Types["__Schema"], + }, + TraceLabel: fmt.Sprintf("GraphQL field: __schema"), + } -var MetaFieldType = Field{ - Field: schema.Field{ - Name: "__type", - Type: schema.Meta.Types["__Type"], - }, - TraceLabel: fmt.Sprintf("GraphQL field: __type"), + fieldType := Field{ + Field: schema.Field{ + Name: "__type", + Type: s.Types["__Type"], + }, + TraceLabel: fmt.Sprintf("GraphQL field: __type"), + } + + return &Meta{ + FieldSchema: fieldSchema, + FieldTypename: fieldTypename, + FieldType: fieldType, + Schema: so, + Type: t, + } } diff --git a/vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/resolvable.go b/vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/resolvable.go index 3e5d9e44d9..e82d35e578 100644 --- a/vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/resolvable.go +++ b/vendor/github.com/graph-gophers/graphql-go/internal/exec/resolvable/resolvable.go @@ -12,10 +12,12 @@ import ( ) type Schema struct { + *Meta schema.Schema - Query Resolvable - Mutation Resolvable - Resolver reflect.Value + Query Resolvable + Mutation Resolvable + Subscription Resolvable + Resolver reflect.Value } type Resolvable interface { @@ -32,6 +34,7 @@ type Field struct { schema.Field TypeName string MethodIndex int + FieldIndex int HasContext bool HasError bool ArgsPacker *packer.StructPacker @@ -39,6 +42,10 @@ type Field struct { TraceLabel string } +func (f *Field) UseMethodResolver() bool { + return f.FieldIndex == -1 +} + type TypeAssertion struct { MethodIndex int TypeExec Resolvable @@ -55,9 +62,13 @@ func (*List) isResolvable() {} func (*Scalar) isResolvable() {} func ApplyResolver(s *schema.Schema, resolver interface{}) (*Schema, error) { + if resolver == nil { + return &Schema{Meta: newMeta(s), Schema: *s}, nil + } + b := newBuilder(s) - var query, mutation Resolvable + var query, mutation, subscription Resolvable if t, ok := s.EntryPoints["query"]; ok { if err := b.assignExec(&query, t, reflect.TypeOf(resolver)); err != nil { @@ -71,15 +82,23 @@ func ApplyResolver(s *schema.Schema, resolver interface{}) (*Schema, error) { } } + if t, ok := s.EntryPoints["subscription"]; ok { + if err := b.assignExec(&subscription, t, reflect.TypeOf(resolver)); err != nil { + return nil, err + } + } + if err := b.finish(); err != nil { return nil, err } return &Schema{ - Schema: *s, - Resolver: reflect.ValueOf(resolver), - Query: query, - Mutation: mutation, + Meta: newMeta(s), + Schema: *s, + Resolver: reflect.ValueOf(resolver), + Query: query, + Mutation: mutation, + Subscription: subscription, }, nil } @@ -181,13 +200,13 @@ func makeScalarExec(t *schema.Scalar, resolverType reflect.Type) (Resolvable, er implementsType := false switch r := reflect.New(resolverType).Interface().(type) { case *int32: - implementsType = (t.Name == "Int") + implementsType = t.Name == "Int" case *float64: - implementsType = (t.Name == "Float") + implementsType = t.Name == "Float" case *string: - implementsType = (t.Name == "String") + implementsType = t.Name == "String" case *bool: - implementsType = (t.Name == "Boolean") + implementsType = t.Name == "Boolean" case packer.Unmarshaler: implementsType = r.ImplementsGraphQLType(t.Name) } @@ -197,7 +216,8 @@ func makeScalarExec(t *schema.Scalar, resolverType reflect.Type) (Resolvable, er return &Scalar{}, nil } -func (b *execBuilder) makeObjectExec(typeName string, fields schema.FieldList, possibleTypes []*schema.Object, nonNull bool, resolverType reflect.Type) (*Object, error) { +func (b *execBuilder) makeObjectExec(typeName string, fields schema.FieldList, possibleTypes []*schema.Object, + nonNull bool, resolverType reflect.Type) (*Object, error) { if !nonNull { if resolverType.Kind() != reflect.Ptr && resolverType.Kind() != reflect.Interface { return nil, fmt.Errorf("%s is not a pointer or interface", resolverType) @@ -207,9 +227,14 @@ func (b *execBuilder) makeObjectExec(typeName string, fields schema.FieldList, p methodHasReceiver := resolverType.Kind() != reflect.Interface Fields := make(map[string]*Field) + rt := unwrapPtr(resolverType) for _, f := range fields { + fieldIndex := -1 methodIndex := findMethod(resolverType, f.Name) - if methodIndex == -1 { + if b.schema.UseFieldResolvers && methodIndex == -1 { + fieldIndex = findField(rt, f.Name) + } + if methodIndex == -1 && fieldIndex == -1 { hint := "" if findMethod(reflect.PtrTo(resolverType), f.Name) != -1 { hint = " (hint: the method exists on the pointer type)" @@ -217,30 +242,41 @@ func (b *execBuilder) makeObjectExec(typeName string, fields schema.FieldList, p return nil, fmt.Errorf("%s does not resolve %q: missing method for field %q%s", resolverType, typeName, f.Name, hint) } - m := resolverType.Method(methodIndex) - fe, err := b.makeFieldExec(typeName, f, m, methodIndex, methodHasReceiver) + var m reflect.Method + var sf reflect.StructField + if methodIndex != -1 { + m = resolverType.Method(methodIndex) + } else { + sf = rt.Field(fieldIndex) + } + fe, err := b.makeFieldExec(typeName, f, m, sf, methodIndex, fieldIndex, methodHasReceiver) if err != nil { return nil, fmt.Errorf("%s\n\treturned by (%s).%s", err, resolverType, m.Name) } Fields[f.Name] = fe } + // Check type assertions when + // 1) using method resolvers + // 2) Or resolver is not an interface type typeAssertions := make(map[string]*TypeAssertion) - for _, impl := range possibleTypes { - methodIndex := findMethod(resolverType, "To"+impl.Name) - if methodIndex == -1 { - return nil, fmt.Errorf("%s does not resolve %q: missing method %q to convert to %q", resolverType, typeName, "To"+impl.Name, impl.Name) + if !b.schema.UseFieldResolvers || resolverType.Kind() != reflect.Interface { + for _, impl := range possibleTypes { + methodIndex := findMethod(resolverType, "To"+impl.Name) + if methodIndex == -1 { + return nil, fmt.Errorf("%s does not resolve %q: missing method %q to convert to %q", resolverType, typeName, "To"+impl.Name, impl.Name) + } + if resolverType.Method(methodIndex).Type.NumOut() != 2 { + return nil, fmt.Errorf("%s does not resolve %q: method %q should return a value and a bool indicating success", resolverType, typeName, "To"+impl.Name) + } + a := &TypeAssertion{ + MethodIndex: methodIndex, + } + if err := b.assignExec(&a.TypeExec, impl, resolverType.Method(methodIndex).Type.Out(0)); err != nil { + return nil, err + } + typeAssertions[impl.Name] = a } - if resolverType.Method(methodIndex).Type.NumOut() != 2 { - return nil, fmt.Errorf("%s does not resolve %q: method %q should return a value and a bool indicating success", resolverType, typeName, "To"+impl.Name) - } - a := &TypeAssertion{ - MethodIndex: methodIndex, - } - if err := b.assignExec(&a.TypeExec, impl, resolverType.Method(methodIndex).Type.Out(0)); err != nil { - return nil, err - } - typeAssertions[impl.Name] = a } return &Object{ @@ -253,45 +289,58 @@ func (b *execBuilder) makeObjectExec(typeName string, fields schema.FieldList, p var contextType = reflect.TypeOf((*context.Context)(nil)).Elem() var errorType = reflect.TypeOf((*error)(nil)).Elem() -func (b *execBuilder) makeFieldExec(typeName string, f *schema.Field, m reflect.Method, methodIndex int, methodHasReceiver bool) (*Field, error) { - in := make([]reflect.Type, m.Type.NumIn()) - for i := range in { - in[i] = m.Type.In(i) - } - if methodHasReceiver { - in = in[1:] // first parameter is receiver - } - - hasContext := len(in) > 0 && in[0] == contextType - if hasContext { - in = in[1:] - } +func (b *execBuilder) makeFieldExec(typeName string, f *schema.Field, m reflect.Method, sf reflect.StructField, + methodIndex, fieldIndex int, methodHasReceiver bool) (*Field, error) { var argsPacker *packer.StructPacker - if len(f.Args) > 0 { - if len(in) == 0 { - return nil, fmt.Errorf("must have parameter for field arguments") + var hasError bool + var hasContext bool + + // Validate resolver method only when there is one + if methodIndex != -1 { + in := make([]reflect.Type, m.Type.NumIn()) + for i := range in { + in[i] = m.Type.In(i) } - var err error - argsPacker, err = b.packerBuilder.MakeStructPacker(f.Args, in[0]) - if err != nil { - return nil, err + if methodHasReceiver { + in = in[1:] // first parameter is receiver } - in = in[1:] - } - if len(in) > 0 { - return nil, fmt.Errorf("too many parameters") - } + hasContext = len(in) > 0 && in[0] == contextType + if hasContext { + in = in[1:] + } - if m.Type.NumOut() > 2 { - return nil, fmt.Errorf("too many return values") - } + if len(f.Args) > 0 { + if len(in) == 0 { + return nil, fmt.Errorf("must have parameter for field arguments") + } + var err error + argsPacker, err = b.packerBuilder.MakeStructPacker(f.Args, in[0]) + if err != nil { + return nil, err + } + in = in[1:] + } - hasError := m.Type.NumOut() == 2 - if hasError { - if m.Type.Out(1) != errorType { - return nil, fmt.Errorf(`must have "error" as its second return value`) + if len(in) > 0 { + return nil, fmt.Errorf("too many parameters") + } + + maxNumOfReturns := 2 + if m.Type.NumOut() < maxNumOfReturns-1 { + return nil, fmt.Errorf("too few return values") + } + + if m.Type.NumOut() > maxNumOfReturns { + return nil, fmt.Errorf("too many return values") + } + + hasError = m.Type.NumOut() == maxNumOfReturns + if hasError { + if m.Type.Out(maxNumOfReturns-1) != errorType { + return nil, fmt.Errorf(`must have "error" as its last return value`) + } } } @@ -299,14 +348,26 @@ func (b *execBuilder) makeFieldExec(typeName string, f *schema.Field, m reflect. Field: *f, TypeName: typeName, MethodIndex: methodIndex, + FieldIndex: fieldIndex, HasContext: hasContext, ArgsPacker: argsPacker, HasError: hasError, TraceLabel: fmt.Sprintf("GraphQL field: %s.%s", typeName, f.Name), } - if err := b.assignExec(&fe.ValueExec, f.Type, m.Type.Out(0)); err != nil { + + var out reflect.Type + if methodIndex != -1 { + out = m.Type.Out(0) + if typeName == "Subscription" && out.Kind() == reflect.Chan { + out = m.Type.Out(0).Elem() + } + } else { + out = sf.Type + } + if err := b.assignExec(&fe.ValueExec, f.Type, out); err != nil { return nil, err } + return fe, nil } @@ -319,6 +380,15 @@ func findMethod(t reflect.Type, name string) int { return -1 } +func findField(t reflect.Type, name string) int { + for i := 0; i < t.NumField(); i++ { + if strings.EqualFold(stripUnderscore(name), stripUnderscore(t.Field(i).Name)) { + return i + } + } + return -1 +} + func unwrapNonNull(t common.Type) (common.Type, bool) { if nn, ok := t.(*common.NonNull); ok { return nn.OfType, true @@ -329,3 +399,10 @@ func unwrapNonNull(t common.Type) (common.Type, bool) { func stripUnderscore(s string) string { return strings.Replace(s, "_", "", -1) } + +func unwrapPtr(t reflect.Type) reflect.Type { + if t.Kind() == reflect.Ptr { + return t.Elem() + } + return t +} diff --git a/vendor/github.com/graph-gophers/graphql-go/internal/exec/selected/selected.go b/vendor/github.com/graph-gophers/graphql-go/internal/exec/selected/selected.go index aed079b671..3075521e07 100644 --- a/vendor/github.com/graph-gophers/graphql-go/internal/exec/selected/selected.go +++ b/vendor/github.com/graph-gophers/graphql-go/internal/exec/selected/selected.go @@ -15,11 +15,12 @@ import ( ) type Request struct { - Schema *schema.Schema - Doc *query.Document - Vars map[string]interface{} - Mu sync.Mutex - Errs []*errors.QueryError + Schema *schema.Schema + Doc *query.Document + Vars map[string]interface{} + Mu sync.Mutex + Errs []*errors.QueryError + DisableIntrospection bool } func (r *Request) AddError(err *errors.QueryError) { @@ -35,8 +36,10 @@ func ApplyOperation(r *Request, s *resolvable.Schema, op *query.Operation) []Sel obj = s.Query.(*resolvable.Object) case query.Mutation: obj = s.Mutation.(*resolvable.Object) + case query.Subscription: + obj = s.Subscription.(*resolvable.Object) } - return applySelectionSet(r, obj, op.Selections) + return applySelectionSet(r, s, obj, op.Selections) } type Selection interface { @@ -67,7 +70,7 @@ func (*SchemaField) isSelection() {} func (*TypeAssertion) isSelection() {} func (*TypenameField) isSelection() {} -func applySelectionSet(r *Request, e *resolvable.Object, sels []query.Selection) (flattenedSels []Selection) { +func applySelectionSet(r *Request, s *resolvable.Schema, e *resolvable.Object, sels []query.Selection) (flattenedSels []Selection) { for _, sel := range sels { switch sel := sel.(type) { case *query.Field: @@ -78,40 +81,46 @@ func applySelectionSet(r *Request, e *resolvable.Object, sels []query.Selection) switch field.Name.Name { case "__typename": - flattenedSels = append(flattenedSels, &TypenameField{ - Object: *e, - Alias: field.Alias.Name, - }) + if !r.DisableIntrospection { + flattenedSels = append(flattenedSels, &TypenameField{ + Object: *e, + Alias: field.Alias.Name, + }) + } case "__schema": - flattenedSels = append(flattenedSels, &SchemaField{ - Field: resolvable.MetaFieldSchema, - Alias: field.Alias.Name, - Sels: applySelectionSet(r, resolvable.MetaSchema, field.Selections), - Async: true, - FixedResult: reflect.ValueOf(introspection.WrapSchema(r.Schema)), - }) + if !r.DisableIntrospection { + flattenedSels = append(flattenedSels, &SchemaField{ + Field: s.Meta.FieldSchema, + Alias: field.Alias.Name, + Sels: applySelectionSet(r, s, s.Meta.Schema, field.Selections), + Async: true, + FixedResult: reflect.ValueOf(introspection.WrapSchema(r.Schema)), + }) + } case "__type": - p := packer.ValuePacker{ValueType: reflect.TypeOf("")} - v, err := p.Pack(field.Arguments.MustGet("name").Value(r.Vars)) - if err != nil { - r.AddError(errors.Errorf("%s", err)) - return nil - } + if !r.DisableIntrospection { + p := packer.ValuePacker{ValueType: reflect.TypeOf("")} + v, err := p.Pack(field.Arguments.MustGet("name").Value(r.Vars)) + if err != nil { + r.AddError(errors.Errorf("%s", err)) + return nil + } - t, ok := r.Schema.Types[v.String()] - if !ok { - return nil - } + t, ok := r.Schema.Types[v.String()] + if !ok { + return nil + } - flattenedSels = append(flattenedSels, &SchemaField{ - Field: resolvable.MetaFieldType, - Alias: field.Alias.Name, - Sels: applySelectionSet(r, resolvable.MetaType, field.Selections), - Async: true, - FixedResult: reflect.ValueOf(introspection.WrapType(t)), - }) + flattenedSels = append(flattenedSels, &SchemaField{ + Field: s.Meta.FieldType, + Alias: field.Alias.Name, + Sels: applySelectionSet(r, s, s.Meta.Type, field.Selections), + Async: true, + FixedResult: reflect.ValueOf(introspection.WrapType(t)), + }) + } default: fe := e.Fields[field.Name.Name] @@ -131,7 +140,7 @@ func applySelectionSet(r *Request, e *resolvable.Object, sels []query.Selection) } } - fieldSels := applyField(r, fe.ValueExec, field.Selections) + fieldSels := applyField(r, s, fe.ValueExec, field.Selections) flattenedSels = append(flattenedSels, &SchemaField{ Field: *fe, Alias: field.Alias.Name, @@ -147,14 +156,14 @@ func applySelectionSet(r *Request, e *resolvable.Object, sels []query.Selection) if skipByDirective(r, frag.Directives) { continue } - flattenedSels = append(flattenedSels, applyFragment(r, e, &frag.Fragment)...) + flattenedSels = append(flattenedSels, applyFragment(r, s, e, &frag.Fragment)...) case *query.FragmentSpread: spread := sel if skipByDirective(r, spread.Directives) { continue } - flattenedSels = append(flattenedSels, applyFragment(r, e, &r.Doc.Fragments.Get(spread.Name.Name).Fragment)...) + flattenedSels = append(flattenedSels, applyFragment(r, s, e, &r.Doc.Fragments.Get(spread.Name.Name).Fragment)...) default: panic("invalid type") @@ -163,7 +172,7 @@ func applySelectionSet(r *Request, e *resolvable.Object, sels []query.Selection) return } -func applyFragment(r *Request, e *resolvable.Object, frag *query.Fragment) []Selection { +func applyFragment(r *Request, s *resolvable.Schema, e *resolvable.Object, frag *query.Fragment) []Selection { if frag.On.Name != "" && frag.On.Name != e.Name { a, ok := e.TypeAssertions[frag.On.Name] if !ok { @@ -172,18 +181,18 @@ func applyFragment(r *Request, e *resolvable.Object, frag *query.Fragment) []Sel return []Selection{&TypeAssertion{ TypeAssertion: *a, - Sels: applySelectionSet(r, a.TypeExec.(*resolvable.Object), frag.Selections), + Sels: applySelectionSet(r, s, a.TypeExec.(*resolvable.Object), frag.Selections), }} } - return applySelectionSet(r, e, frag.Selections) + return applySelectionSet(r, s, e, frag.Selections) } -func applyField(r *Request, e resolvable.Resolvable, sels []query.Selection) []Selection { +func applyField(r *Request, s *resolvable.Schema, e resolvable.Resolvable, sels []query.Selection) []Selection { switch e := e.(type) { case *resolvable.Object: - return applySelectionSet(r, e, sels) + return applySelectionSet(r, s, e, sels) case *resolvable.List: - return applyField(r, e.Elem, sels) + return applyField(r, s, e.Elem, sels) case *resolvable.Scalar: return nil default: diff --git a/vendor/github.com/graph-gophers/graphql-go/internal/query/query.go b/vendor/github.com/graph-gophers/graphql-go/internal/query/query.go index faba4d2ade..fffc88e7f1 100644 --- a/vendor/github.com/graph-gophers/graphql-go/internal/query/query.go +++ b/vendor/github.com/graph-gophers/graphql-go/internal/query/query.go @@ -94,7 +94,7 @@ func (InlineFragment) isSelection() {} func (FragmentSpread) isSelection() {} func Parse(queryString string) (*Document, *errors.QueryError) { - l := common.NewLexer(queryString) + l := common.NewLexer(queryString, false) var doc *Document err := l.CatchSyntaxError(func() { doc = parseDocument(l) }) @@ -107,7 +107,7 @@ func Parse(queryString string) (*Document, *errors.QueryError) { func parseDocument(l *common.Lexer) *Document { d := &Document{} - l.Consume() + l.ConsumeWhitespace() for l.Peek() != scanner.EOF { if l.Peek() == '{' { op := &Operation{Type: Query, Loc: l.Location()} diff --git a/vendor/github.com/graph-gophers/graphql-go/internal/schema/meta.go b/vendor/github.com/graph-gophers/graphql-go/internal/schema/meta.go index b48bf7acf2..2e31183016 100644 --- a/vendor/github.com/graph-gophers/graphql-go/internal/schema/meta.go +++ b/vendor/github.com/graph-gophers/graphql-go/internal/schema/meta.go @@ -1,13 +1,20 @@ package schema -var Meta *Schema - func init() { - Meta = &Schema{} // bootstrap - Meta = New() - if err := Meta.Parse(metaSrc); err != nil { + _ = newMeta() +} + +// newMeta initializes an instance of the meta Schema. +func newMeta() *Schema { + s := &Schema{ + entryPointNames: make(map[string]string), + Types: make(map[string]NamedType), + Directives: make(map[string]*DirectiveDecl), + } + if err := s.Parse(metaSrc, false); err != nil { panic(err) } + return s } var metaSrc = ` @@ -167,7 +174,7 @@ var metaSrc = ` inputFields: [__InputValue!] ofType: __Type } - + # An enum describing what kind of type a given ` + "`" + `__Type` + "`" + ` is. enum __TypeKind { # Indicates this type is a scalar. diff --git a/vendor/github.com/graph-gophers/graphql-go/internal/schema/schema.go b/vendor/github.com/graph-gophers/graphql-go/internal/schema/schema.go index e549f17c07..982e225b2b 100644 --- a/vendor/github.com/graph-gophers/graphql-go/internal/schema/schema.go +++ b/vendor/github.com/graph-gophers/graphql-go/internal/schema/schema.go @@ -41,6 +41,8 @@ type Schema struct { // http://facebook.github.io/graphql/draft/#sec-Type-System.Directives Directives map[string]*DirectiveDecl + UseFieldResolvers bool + entryPointNames map[string]string objects []*Object unions []*Union @@ -236,18 +238,19 @@ func New() *Schema { Types: make(map[string]NamedType), Directives: make(map[string]*DirectiveDecl), } - for n, t := range Meta.Types { + m := newMeta() + for n, t := range m.Types { s.Types[n] = t } - for n, d := range Meta.Directives { + for n, d := range m.Directives { s.Directives[n] = d } return s } // Parse the schema string. -func (s *Schema) Parse(schemaString string) error { - l := common.NewLexer(schemaString) +func (s *Schema) Parse(schemaString string, useStringDescriptions bool) error { + l := common.NewLexer(schemaString, useStringDescriptions) err := l.CatchSyntaxError(func() { parseSchema(s, l) }) if err != nil { @@ -291,6 +294,11 @@ func (s *Schema) Parse(schemaString string) error { if !ok { return errors.Errorf("type %q is not an interface", intfName) } + for _, f := range intf.Fields.Names() { + if obj.Fields.Get(f) == nil { + return errors.Errorf("interface %q expects field %q but %q does not provide it", intfName, f, obj.Name) + } + } obj.Interfaces[i] = intf intf.PossibleTypes = append(intf.PossibleTypes, obj) } @@ -389,7 +397,7 @@ func resolveInputObject(s *Schema, values common.InputValueList) error { } func parseSchema(s *Schema, l *common.Lexer) { - l.Consume() + l.ConsumeWhitespace() for l.Peek() != scanner.EOF { desc := l.DescComment() diff --git a/vendor/github.com/graph-gophers/graphql-go/internal/validation/validation.go b/vendor/github.com/graph-gophers/graphql-go/internal/validation/validation.go index 94ad5ca7fb..94a9faf8e9 100644 --- a/vendor/github.com/graph-gophers/graphql-go/internal/validation/validation.go +++ b/vendor/github.com/graph-gophers/graphql-go/internal/validation/validation.go @@ -63,7 +63,7 @@ func newContext(s *schema.Schema, doc *query.Document, maxDepth int) *context { } } -func Validate(s *schema.Schema, doc *query.Document, maxDepth int) []*errors.QueryError { +func Validate(s *schema.Schema, doc *query.Document, variables map[string]interface{}, maxDepth int) []*errors.QueryError { c := newContext(s, doc, maxDepth) opNames := make(nameSet) @@ -95,6 +95,7 @@ func Validate(s *schema.Schema, doc *query.Document, maxDepth int) []*errors.Que if !canBeInput(t) { c.addErr(v.TypeLoc, "VariablesAreInputTypes", "Variable %q cannot be non-input type %q.", "$"+v.Name.Name, t) } + validateValue(opc, v, variables[v.Name.Name], t) if v.Default != nil { validateLiteral(opc, v.Default) @@ -178,6 +179,58 @@ func Validate(s *schema.Schema, doc *query.Document, maxDepth int) []*errors.Que return c.errs } +func validateValue(c *opContext, v *common.InputValue, val interface{}, t common.Type) { + switch t := t.(type) { + case *common.NonNull: + if val == nil { + c.addErr(v.Loc, "VariablesOfCorrectType", "Variable \"%s\" has invalid value null.\nExpected type \"%s\", found null.", v.Name.Name, t) + return + } + validateValue(c, v, val, t.OfType) + case *common.List: + if val == nil { + return + } + vv, ok := val.([]interface{}) + if !ok { + // Input coercion rules allow single items without wrapping array + validateValue(c, v, val, t.OfType) + return + } + for _, elem := range vv { + validateValue(c, v, elem, t.OfType) + } + case *schema.Enum: + if val == nil { + return + } + e, ok := val.(string) + if !ok { + c.addErr(v.Loc, "VariablesOfCorrectType", "Variable \"%s\" has invalid type %T.\nExpected type \"%s\", found %v.", v.Name.Name, val, t, val) + return + } + for _, option := range t.Values { + if option.Name == e { + return + } + } + c.addErr(v.Loc, "VariablesOfCorrectType", "Variable \"%s\" has invalid value %s.\nExpected type \"%s\", found %s.", v.Name.Name, e, t, e) + case *schema.InputObject: + if val == nil { + return + } + in, ok := val.(map[string]interface{}) + if !ok { + c.addErr(v.Loc, "VariablesOfCorrectType", "Variable \"%s\" has invalid type %T.\nExpected type \"%s\", found %s.", v.Name.Name, val, t, val) + return + } + for _, f := range t.Values { + fieldVal := in[f.Name.Name] + validateValue(c, f, fieldVal, f.Type) + } + } +} + // validates the query doesn't go deeper than maxDepth (if set). Returns whether // or not query validated max depth to avoid excessive recursion. func validateMaxDepth(c *opContext, sels []query.Selection, depth int) bool { @@ -686,6 +739,7 @@ func validateLiteral(c *opContext, l common.Literal) { }) continue } + validateValueType(c, l, resolveType(c.context, v.Type)) c.usedVars[op][v] = struct{}{} } } diff --git a/vendor/github.com/graph-gophers/graphql-go/introspection.go b/vendor/github.com/graph-gophers/graphql-go/introspection.go index 7e515cf25f..6877bcaf39 100644 --- a/vendor/github.com/graph-gophers/graphql-go/introspection.go +++ b/vendor/github.com/graph-gophers/graphql-go/introspection.go @@ -16,6 +16,7 @@ func (s *Schema) Inspect() *introspection.Schema { // ToJSON encodes the schema in a JSON format used by tools like Relay. func (s *Schema) ToJSON() ([]byte, error) { result := s.exec(context.Background(), introspectionQuery, "", nil, &resolvable.Schema{ + Meta: s.res.Meta, Query: &resolvable.Object{}, Schema: *s.schema, }) diff --git a/vendor/github.com/hashicorp/golang-lru/2q.go b/vendor/github.com/hashicorp/golang-lru/2q.go index 337d963296..e474cd0758 100644 --- a/vendor/github.com/hashicorp/golang-lru/2q.go +++ b/vendor/github.com/hashicorp/golang-lru/2q.go @@ -30,9 +30,9 @@ type TwoQueueCache struct { size int recentSize int - recent *simplelru.LRU - frequent *simplelru.LRU - recentEvict *simplelru.LRU + recent simplelru.LRUCache + frequent simplelru.LRUCache + recentEvict simplelru.LRUCache lock sync.RWMutex } @@ -84,7 +84,8 @@ func New2QParams(size int, recentRatio float64, ghostRatio float64) (*TwoQueueCa return c, nil } -func (c *TwoQueueCache) Get(key interface{}) (interface{}, bool) { +// Get looks up a key's value from the cache. +func (c *TwoQueueCache) Get(key interface{}) (value interface{}, ok bool) { c.lock.Lock() defer c.lock.Unlock() @@ -105,6 +106,7 @@ func (c *TwoQueueCache) Get(key interface{}) (interface{}, bool) { return nil, false } +// Add adds a value to the cache. func (c *TwoQueueCache) Add(key, value interface{}) { c.lock.Lock() defer c.lock.Unlock() @@ -160,12 +162,15 @@ func (c *TwoQueueCache) ensureSpace(recentEvict bool) { c.frequent.RemoveOldest() } +// Len returns the number of items in the cache. func (c *TwoQueueCache) Len() int { c.lock.RLock() defer c.lock.RUnlock() return c.recent.Len() + c.frequent.Len() } +// Keys returns a slice of the keys in the cache. +// The frequently used keys are first in the returned slice. func (c *TwoQueueCache) Keys() []interface{} { c.lock.RLock() defer c.lock.RUnlock() @@ -174,6 +179,7 @@ func (c *TwoQueueCache) Keys() []interface{} { return append(k1, k2...) } +// Remove removes the provided key from the cache. func (c *TwoQueueCache) Remove(key interface{}) { c.lock.Lock() defer c.lock.Unlock() @@ -188,6 +194,7 @@ func (c *TwoQueueCache) Remove(key interface{}) { } } +// Purge is used to completely clear the cache. func (c *TwoQueueCache) Purge() { c.lock.Lock() defer c.lock.Unlock() @@ -196,13 +203,17 @@ func (c *TwoQueueCache) Purge() { c.recentEvict.Purge() } +// Contains is used to check if the cache contains a key +// without updating recency or frequency. func (c *TwoQueueCache) Contains(key interface{}) bool { c.lock.RLock() defer c.lock.RUnlock() return c.frequent.Contains(key) || c.recent.Contains(key) } -func (c *TwoQueueCache) Peek(key interface{}) (interface{}, bool) { +// Peek is used to inspect the cache value of a key +// without updating recency or frequency. +func (c *TwoQueueCache) Peek(key interface{}) (value interface{}, ok bool) { c.lock.RLock() defer c.lock.RUnlock() if val, ok := c.frequent.Peek(key); ok { diff --git a/vendor/github.com/hashicorp/golang-lru/arc.go b/vendor/github.com/hashicorp/golang-lru/arc.go index a2a2528173..555225a218 100644 --- a/vendor/github.com/hashicorp/golang-lru/arc.go +++ b/vendor/github.com/hashicorp/golang-lru/arc.go @@ -18,11 +18,11 @@ type ARCCache struct { size int // Size is the total capacity of the cache p int // P is the dynamic preference towards T1 or T2 - t1 *simplelru.LRU // T1 is the LRU for recently accessed items - b1 *simplelru.LRU // B1 is the LRU for evictions from t1 + t1 simplelru.LRUCache // T1 is the LRU for recently accessed items + b1 simplelru.LRUCache // B1 is the LRU for evictions from t1 - t2 *simplelru.LRU // T2 is the LRU for frequently accessed items - b2 *simplelru.LRU // B2 is the LRU for evictions from t2 + t2 simplelru.LRUCache // T2 is the LRU for frequently accessed items + b2 simplelru.LRUCache // B2 is the LRU for evictions from t2 lock sync.RWMutex } @@ -60,11 +60,11 @@ func NewARC(size int) (*ARCCache, error) { } // Get looks up a key's value from the cache. -func (c *ARCCache) Get(key interface{}) (interface{}, bool) { +func (c *ARCCache) Get(key interface{}) (value interface{}, ok bool) { c.lock.Lock() defer c.lock.Unlock() - // Ff the value is contained in T1 (recent), then + // If the value is contained in T1 (recent), then // promote it to T2 (frequent) if val, ok := c.t1.Peek(key); ok { c.t1.Remove(key) @@ -153,7 +153,7 @@ func (c *ARCCache) Add(key, value interface{}) { // Remove from B2 c.b2.Remove(key) - // Add the key to the frequntly used list + // Add the key to the frequently used list c.t2.Add(key, value) return } @@ -247,7 +247,7 @@ func (c *ARCCache) Contains(key interface{}) bool { // Peek is used to inspect the cache value of a key // without updating recency or frequency. -func (c *ARCCache) Peek(key interface{}) (interface{}, bool) { +func (c *ARCCache) Peek(key interface{}) (value interface{}, ok bool) { c.lock.RLock() defer c.lock.RUnlock() if val, ok := c.t1.Peek(key); ok { diff --git a/vendor/github.com/hashicorp/golang-lru/lru.go b/vendor/github.com/hashicorp/golang-lru/lru.go index a6285f989e..1cbe04b7d0 100644 --- a/vendor/github.com/hashicorp/golang-lru/lru.go +++ b/vendor/github.com/hashicorp/golang-lru/lru.go @@ -1,6 +1,3 @@ -// This package provides a simple LRU cache. It is based on the -// LRU implementation in groupcache: -// https://github.com/golang/groupcache/tree/master/lru package lru import ( @@ -11,11 +8,11 @@ import ( // Cache is a thread-safe fixed size LRU cache. type Cache struct { - lru *simplelru.LRU + lru simplelru.LRUCache lock sync.RWMutex } -// New creates an LRU of the given size +// New creates an LRU of the given size. func New(size int) (*Cache, error) { return NewWithEvict(size, nil) } @@ -33,7 +30,7 @@ func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) return c, nil } -// Purge is used to completely clear the cache +// Purge is used to completely clear the cache. func (c *Cache) Purge() { c.lock.Lock() c.lru.Purge() @@ -41,48 +38,51 @@ func (c *Cache) Purge() { } // Add adds a value to the cache. Returns true if an eviction occurred. -func (c *Cache) Add(key, value interface{}) bool { +func (c *Cache) Add(key, value interface{}) (evicted bool) { c.lock.Lock() - defer c.lock.Unlock() - return c.lru.Add(key, value) + evicted = c.lru.Add(key, value) + c.lock.Unlock() + return evicted } // Get looks up a key's value from the cache. -func (c *Cache) Get(key interface{}) (interface{}, bool) { +func (c *Cache) Get(key interface{}) (value interface{}, ok bool) { c.lock.Lock() - defer c.lock.Unlock() - return c.lru.Get(key) + value, ok = c.lru.Get(key) + c.lock.Unlock() + return value, ok } -// Check if a key is in the cache, without updating the recent-ness -// or deleting it for being stale. +// Contains checks if a key is in the cache, without updating the +// recent-ness or deleting it for being stale. func (c *Cache) Contains(key interface{}) bool { c.lock.RLock() - defer c.lock.RUnlock() - return c.lru.Contains(key) + containKey := c.lru.Contains(key) + c.lock.RUnlock() + return containKey } -// Returns the key value (or undefined if not found) without updating +// Peek returns the key value (or undefined if not found) without updating // the "recently used"-ness of the key. -func (c *Cache) Peek(key interface{}) (interface{}, bool) { +func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) { c.lock.RLock() - defer c.lock.RUnlock() - return c.lru.Peek(key) + value, ok = c.lru.Peek(key) + c.lock.RUnlock() + return value, ok } // ContainsOrAdd checks if a key is in the cache without updating the // recent-ness or deleting it for being stale, and if not, adds the value. // Returns whether found and whether an eviction occurred. -func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evict bool) { +func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) { c.lock.Lock() defer c.lock.Unlock() if c.lru.Contains(key) { return true, false - } else { - evict := c.lru.Add(key, value) - return false, evict } + evicted = c.lru.Add(key, value) + return false, evicted } // Remove removes the provided key from the cache. @@ -102,13 +102,15 @@ func (c *Cache) RemoveOldest() { // Keys returns a slice of the keys in the cache, from oldest to newest. func (c *Cache) Keys() []interface{} { c.lock.RLock() - defer c.lock.RUnlock() - return c.lru.Keys() + keys := c.lru.Keys() + c.lock.RUnlock() + return keys } // Len returns the number of items in the cache. func (c *Cache) Len() int { c.lock.RLock() - defer c.lock.RUnlock() - return c.lru.Len() + length := c.lru.Len() + c.lock.RUnlock() + return length } diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go index cb416b394f..ff2f63886f 100644 --- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go +++ b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go @@ -36,7 +36,7 @@ func NewLRU(size int, onEvict EvictCallback) (*LRU, error) { return c, nil } -// Purge is used to completely clear the cache +// Purge is used to completely clear the cache. func (c *LRU) Purge() { for k, v := range c.items { if c.onEvict != nil { @@ -48,7 +48,7 @@ func (c *LRU) Purge() { } // Add adds a value to the cache. Returns true if an eviction occurred. -func (c *LRU) Add(key, value interface{}) bool { +func (c *LRU) Add(key, value interface{}) (evicted bool) { // Check for existing item if ent, ok := c.items[key]; ok { c.evictList.MoveToFront(ent) @@ -73,22 +73,26 @@ func (c *LRU) Add(key, value interface{}) bool { func (c *LRU) Get(key interface{}) (value interface{}, ok bool) { if ent, ok := c.items[key]; ok { c.evictList.MoveToFront(ent) + if ent.Value.(*entry) == nil { + return nil, false + } return ent.Value.(*entry).value, true } return } -// Check if a key is in the cache, without updating the recent-ness +// Contains checks if a key is in the cache, without updating the recent-ness // or deleting it for being stale. func (c *LRU) Contains(key interface{}) (ok bool) { _, ok = c.items[key] return ok } -// Returns the key value (or undefined if not found) without updating +// Peek returns the key value (or undefined if not found) without updating // the "recently used"-ness of the key. func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) { - if ent, ok := c.items[key]; ok { + var ent *list.Element + if ent, ok = c.items[key]; ok { return ent.Value.(*entry).value, true } return nil, ok @@ -96,7 +100,7 @@ func (c *LRU) Peek(key interface{}) (value interface{}, ok bool) { // Remove removes the provided key from the cache, returning if the // key was contained. -func (c *LRU) Remove(key interface{}) bool { +func (c *LRU) Remove(key interface{}) (present bool) { if ent, ok := c.items[key]; ok { c.removeElement(ent) return true @@ -105,7 +109,7 @@ func (c *LRU) Remove(key interface{}) bool { } // RemoveOldest removes the oldest item from the cache. -func (c *LRU) RemoveOldest() (interface{}, interface{}, bool) { +func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { ent := c.evictList.Back() if ent != nil { c.removeElement(ent) @@ -116,7 +120,7 @@ func (c *LRU) RemoveOldest() (interface{}, interface{}, bool) { } // GetOldest returns the oldest entry -func (c *LRU) GetOldest() (interface{}, interface{}, bool) { +func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) { ent := c.evictList.Back() if ent != nil { kv := ent.Value.(*entry) diff --git a/vendor/github.com/huin/goupnp/LICENSE b/vendor/github.com/huin/goupnp/LICENSE index 252e3d6397..c5a45bcbf6 100644 --- a/vendor/github.com/huin/goupnp/LICENSE +++ b/vendor/github.com/huin/goupnp/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013, John Beisley +Copyright (c) 2013, John Beisley All rights reserved. Redistribution and use in source and binary forms, with or without modification, diff --git a/vendor/github.com/huin/goupnp/README.md b/vendor/github.com/huin/goupnp/README.md index 433ba5c682..7c63903aeb 100644 --- a/vendor/github.com/huin/goupnp/README.md +++ b/vendor/github.com/huin/goupnp/README.md @@ -25,15 +25,19 @@ Core components: Regenerating dcps generated source code: ---------------------------------------- -1. Install gotasks: `go get -u github.com/jingweno/gotask` -2. Change to the gotasks directory: `cd gotasks` -3. Run specgen task: `gotask specgen` +1. Build code generator: + + `go get -u github.com/huin/goupnp/cmd/goupnpdcpgen` + +2. Regenerate the code: + + `go generate ./...` Supporting additional UPnP devices and services: ------------------------------------------------ Supporting additional services is, in the trivial case, simply a matter of -adding the service to the `dcpMetadata` whitelist in `gotasks/specgen_task.go`, +adding the service to the `dcpMetadata` whitelist in `cmd/goupnpdcpgen/metadata.go`, regenerating the source code (see above), and committing that source code. However, it would be helpful if anyone needing such a service could test the diff --git a/vendor/github.com/huin/goupnp/dcps/internetgateway1/internetgateway1.go b/vendor/github.com/huin/goupnp/dcps/internetgateway1/internetgateway1.go index 1e0802cd4e..e9335047c8 100644 --- a/vendor/github.com/huin/goupnp/dcps/internetgateway1/internetgateway1.go +++ b/vendor/github.com/huin/goupnp/dcps/internetgateway1/internetgateway1.go @@ -5,7 +5,9 @@ // Typically, use one of the New* functions to create clients for services. package internetgateway1 -// Generated file - do not edit by hand. See README.md +// *********************************************************** +// GENERATED FILE - DO NOT EDIT BY HAND. See README.md +// *********************************************************** import ( "net/url" @@ -388,7 +390,6 @@ func (client *LANHostConfigManagement1) SetAddressRange(NewMinAddress string, Ne // Request structure. request := &struct { NewMinAddress string - NewMaxAddress string }{} // BEGIN Marshal arguments into request. @@ -425,7 +426,6 @@ func (client *LANHostConfigManagement1) GetAddressRange() (NewMinAddress string, // Response structure. response := &struct { NewMinAddress string - NewMaxAddress string }{} @@ -790,8 +790,7 @@ func (client *WANCableLinkConfig1) GetCableLinkConfigInfo() (NewCableLinkConfigS // Response structure. response := &struct { NewCableLinkConfigState string - - NewLinkType string + NewLinkType string }{} // Perform the SOAP call. @@ -1180,13 +1179,10 @@ func (client *WANCommonInterfaceConfig1) GetCommonLinkProperties() (NewWANAccess // Response structure. response := &struct { - NewWANAccessType string - - NewLayer1UpstreamMaxBitRate string - + NewWANAccessType string + NewLayer1UpstreamMaxBitRate string NewLayer1DownstreamMaxBitRate string - - NewPhysicalLinkStatus string + NewPhysicalLinkStatus string }{} // Perform the SOAP call. @@ -1268,7 +1264,7 @@ func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnections() (NewMaxim return } -func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint32, err error) { +func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint64, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. @@ -1287,14 +1283,14 @@ func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent // BEGIN Unmarshal arguments from response. - if NewTotalBytesSent, err = soap.UnmarshalUi4(response.NewTotalBytesSent); err != nil { + if NewTotalBytesSent, err = soap.UnmarshalUi8(response.NewTotalBytesSent); err != nil { return } // END Unmarshal arguments from response. return } -func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint32, err error) { +func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint64, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. @@ -1313,7 +1309,7 @@ func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesR // BEGIN Unmarshal arguments from response. - if NewTotalBytesReceived, err = soap.UnmarshalUi4(response.NewTotalBytesReceived); err != nil { + if NewTotalBytesReceived, err = soap.UnmarshalUi8(response.NewTotalBytesReceived); err != nil { return } // END Unmarshal arguments from response. @@ -1387,7 +1383,6 @@ func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnection // Response structure. response := &struct { NewActiveConnDeviceContainer string - NewActiveConnectionServiceID string }{} @@ -1507,8 +1502,7 @@ func (client *WANDSLLinkConfig1) GetDSLLinkInfo() (NewLinkType string, NewLinkSt // Response structure. response := &struct { - NewLinkType string - + NewLinkType string NewLinkStatus string }{} @@ -1926,8 +1920,7 @@ func (client *WANIPConnection1) GetConnectionTypeInfo() (NewConnectionType strin // Response structure. response := &struct { - NewConnectionType string - + NewConnectionType string NewPossibleConnectionTypes string }{} @@ -2104,11 +2097,9 @@ func (client *WANIPConnection1) GetStatusInfo() (NewConnectionStatus string, New // Response structure. response := &struct { - NewConnectionStatus string - + NewConnectionStatus string NewLastConnectionError string - - NewUptime string + NewUptime string }{} // Perform the SOAP call. @@ -2219,8 +2210,7 @@ func (client *WANIPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNA // Response structure. response := &struct { NewRSIPAvailable string - - NewNATEnabled string + NewNATEnabled string }{} // Perform the SOAP call. @@ -2258,21 +2248,14 @@ func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex u // Response structure. response := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // Perform the SOAP call. @@ -2318,11 +2301,9 @@ func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex u func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { // Request structure. request := &struct { - NewRemoteHost string - + NewRemoteHost string NewExternalPort string - - NewProtocol string + NewProtocol string }{} // BEGIN Marshal arguments into request. @@ -2339,15 +2320,11 @@ func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string // Response structure. response := &struct { - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // Perform the SOAP call. @@ -2384,21 +2361,14 @@ func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { // Request structure. request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // BEGIN Marshal arguments into request. @@ -2450,11 +2420,9 @@ func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternal func (client *WANIPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { // Request structure. request := &struct { - NewRemoteHost string - + NewRemoteHost string NewExternalPort string - - NewProtocol string + NewProtocol string }{} // BEGIN Marshal arguments into request. @@ -2578,10 +2546,8 @@ func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInf // Request structure. request := &struct { NewISPPhoneNumber string - - NewISPInfo string - - NewLinkType string + NewISPInfo string + NewLinkType string }{} // BEGIN Marshal arguments into request. @@ -2613,8 +2579,7 @@ func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInf func (client *WANPOTSLinkConfig1) SetCallRetryInfo(NewNumberOfRetries uint32, NewDelayBetweenRetries uint32) (err error) { // Request structure. request := &struct { - NewNumberOfRetries string - + NewNumberOfRetries string NewDelayBetweenRetries string }{} // BEGIN Marshal arguments into request. @@ -2655,10 +2620,8 @@ func (client *WANPOTSLinkConfig1) GetISPInfo() (NewISPPhoneNumber string, NewISP // Response structure. response := &struct { NewISPPhoneNumber string - - NewISPInfo string - - NewLinkType string + NewISPInfo string + NewLinkType string }{} // Perform the SOAP call. @@ -2690,8 +2653,7 @@ func (client *WANPOTSLinkConfig1) GetCallRetryInfo() (NewNumberOfRetries uint32, // Response structure. response := &struct { - NewNumberOfRetries string - + NewNumberOfRetries string NewDelayBetweenRetries string }{} @@ -2941,8 +2903,7 @@ func (client *WANPPPConnection1) GetConnectionTypeInfo() (NewConnectionType stri // Response structure. response := &struct { - NewConnectionType string - + NewConnectionType string NewPossibleConnectionTypes string }{} @@ -2967,7 +2928,6 @@ func (client *WANPPPConnection1) ConfigureConnection(NewUserName string, NewPass // Request structure. request := &struct { NewUserName string - NewPassword string }{} // BEGIN Marshal arguments into request. @@ -3150,11 +3110,9 @@ func (client *WANPPPConnection1) GetStatusInfo() (NewConnectionStatus string, Ne // Response structure. response := &struct { - NewConnectionStatus string - + NewConnectionStatus string NewLastConnectionError string - - NewUptime string + NewUptime string }{} // Perform the SOAP call. @@ -3186,8 +3144,7 @@ func (client *WANPPPConnection1) GetLinkLayerMaxBitRates() (NewUpstreamMaxBitRat // Response structure. response := &struct { - NewUpstreamMaxBitRate string - + NewUpstreamMaxBitRate string NewDownstreamMaxBitRate string }{} @@ -3426,8 +3383,7 @@ func (client *WANPPPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewN // Response structure. response := &struct { NewRSIPAvailable string - - NewNATEnabled string + NewNATEnabled string }{} // Perform the SOAP call. @@ -3465,21 +3421,14 @@ func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex // Response structure. response := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // Perform the SOAP call. @@ -3525,11 +3474,9 @@ func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { // Request structure. request := &struct { - NewRemoteHost string - + NewRemoteHost string NewExternalPort string - - NewProtocol string + NewProtocol string }{} // BEGIN Marshal arguments into request. @@ -3546,15 +3493,11 @@ func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost strin // Response structure. response := &struct { - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // Perform the SOAP call. @@ -3591,21 +3534,14 @@ func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost strin func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { // Request structure. request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // BEGIN Marshal arguments into request. @@ -3657,11 +3593,9 @@ func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExterna func (client *WANPPPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { // Request structure. request := &struct { - NewRemoteHost string - + NewRemoteHost string NewExternalPort string - - NewProtocol string + NewProtocol string }{} // BEGIN Marshal arguments into request. diff --git a/vendor/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go b/vendor/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go index 2d67a4a2e2..4eb5f61052 100644 --- a/vendor/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go +++ b/vendor/github.com/huin/goupnp/dcps/internetgateway2/internetgateway2.go @@ -5,7 +5,9 @@ // Typically, use one of the New* functions to create clients for services. package internetgateway2 -// Generated file - do not edit by hand. See README.md +// *********************************************************** +// GENERATED FILE - DO NOT EDIT BY HAND. See README.md +// *********************************************************** import ( "net/url" @@ -107,8 +109,7 @@ func (client *DeviceProtection1) SendSetupMessage(ProtocolType string, InMessage // Request structure. request := &struct { ProtocolType string - - InMessage string + InMessage string }{} // BEGIN Marshal arguments into request. @@ -194,10 +195,8 @@ func (client *DeviceProtection1) GetAssignedRoles() (RoleList string, err error) func (client *DeviceProtection1) GetRolesForAction(DeviceUDN string, ServiceId string, ActionName string) (RoleList string, RestrictedRoleList string, err error) { // Request structure. request := &struct { - DeviceUDN string - - ServiceId string - + DeviceUDN string + ServiceId string ActionName string }{} // BEGIN Marshal arguments into request. @@ -215,8 +214,7 @@ func (client *DeviceProtection1) GetRolesForAction(DeviceUDN string, ServiceId s // Response structure. response := &struct { - RoleList string - + RoleList string RestrictedRoleList string }{} @@ -241,8 +239,7 @@ func (client *DeviceProtection1) GetUserLoginChallenge(ProtocolType string, Name // Request structure. request := &struct { ProtocolType string - - Name string + Name string }{} // BEGIN Marshal arguments into request. @@ -256,8 +253,7 @@ func (client *DeviceProtection1) GetUserLoginChallenge(ProtocolType string, Name // Response structure. response := &struct { - Salt string - + Salt string Challenge string }{} @@ -281,10 +277,8 @@ func (client *DeviceProtection1) GetUserLoginChallenge(ProtocolType string, Name func (client *DeviceProtection1) UserLogin(ProtocolType string, Challenge []byte, Authenticator []byte) (err error) { // Request structure. request := &struct { - ProtocolType string - - Challenge string - + ProtocolType string + Challenge string Authenticator string }{} // BEGIN Marshal arguments into request. @@ -422,12 +416,9 @@ func (client *DeviceProtection1) SetUserLoginPassword(ProtocolType string, Name // Request structure. request := &struct { ProtocolType string - - Name string - - Stored string - - Salt string + Name string + Stored string + Salt string }{} // BEGIN Marshal arguments into request. @@ -463,7 +454,6 @@ func (client *DeviceProtection1) AddRolesForIdentity(Identity string, RoleList s // Request structure. request := &struct { Identity string - RoleList string }{} // BEGIN Marshal arguments into request. @@ -494,7 +484,6 @@ func (client *DeviceProtection1) RemoveRolesForIdentity(Identity string, RoleLis // Request structure. request := &struct { Identity string - RoleList string }{} // BEGIN Marshal arguments into request. @@ -871,7 +860,6 @@ func (client *LANHostConfigManagement1) SetAddressRange(NewMinAddress string, Ne // Request structure. request := &struct { NewMinAddress string - NewMaxAddress string }{} // BEGIN Marshal arguments into request. @@ -908,7 +896,6 @@ func (client *LANHostConfigManagement1) GetAddressRange() (NewMinAddress string, // Response structure. response := &struct { NewMinAddress string - NewMaxAddress string }{} @@ -1273,8 +1260,7 @@ func (client *WANCableLinkConfig1) GetCableLinkConfigInfo() (NewCableLinkConfigS // Response structure. response := &struct { NewCableLinkConfigState string - - NewLinkType string + NewLinkType string }{} // Perform the SOAP call. @@ -1663,13 +1649,10 @@ func (client *WANCommonInterfaceConfig1) GetCommonLinkProperties() (NewWANAccess // Response structure. response := &struct { - NewWANAccessType string - - NewLayer1UpstreamMaxBitRate string - + NewWANAccessType string + NewLayer1UpstreamMaxBitRate string NewLayer1DownstreamMaxBitRate string - - NewPhysicalLinkStatus string + NewPhysicalLinkStatus string }{} // Perform the SOAP call. @@ -1751,7 +1734,7 @@ func (client *WANCommonInterfaceConfig1) GetMaximumActiveConnections() (NewMaxim return } -func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint32, err error) { +func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent uint64, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. @@ -1770,14 +1753,14 @@ func (client *WANCommonInterfaceConfig1) GetTotalBytesSent() (NewTotalBytesSent // BEGIN Unmarshal arguments from response. - if NewTotalBytesSent, err = soap.UnmarshalUi4(response.NewTotalBytesSent); err != nil { + if NewTotalBytesSent, err = soap.UnmarshalUi8(response.NewTotalBytesSent); err != nil { return } // END Unmarshal arguments from response. return } -func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint32, err error) { +func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesReceived uint64, err error) { // Request structure. request := interface{}(nil) // BEGIN Marshal arguments into request. @@ -1796,7 +1779,7 @@ func (client *WANCommonInterfaceConfig1) GetTotalBytesReceived() (NewTotalBytesR // BEGIN Unmarshal arguments from response. - if NewTotalBytesReceived, err = soap.UnmarshalUi4(response.NewTotalBytesReceived); err != nil { + if NewTotalBytesReceived, err = soap.UnmarshalUi8(response.NewTotalBytesReceived); err != nil { return } // END Unmarshal arguments from response. @@ -1870,7 +1853,6 @@ func (client *WANCommonInterfaceConfig1) GetActiveConnection(NewActiveConnection // Response structure. response := &struct { NewActiveConnDeviceContainer string - NewActiveConnectionServiceID string }{} @@ -1990,8 +1972,7 @@ func (client *WANDSLLinkConfig1) GetDSLLinkInfo() (NewLinkType string, NewLinkSt // Response structure. response := &struct { - NewLinkType string - + NewLinkType string NewLinkStatus string }{} @@ -2409,8 +2390,7 @@ func (client *WANIPConnection1) GetConnectionTypeInfo() (NewConnectionType strin // Response structure. response := &struct { - NewConnectionType string - + NewConnectionType string NewPossibleConnectionTypes string }{} @@ -2587,11 +2567,9 @@ func (client *WANIPConnection1) GetStatusInfo() (NewConnectionStatus string, New // Response structure. response := &struct { - NewConnectionStatus string - + NewConnectionStatus string NewLastConnectionError string - - NewUptime string + NewUptime string }{} // Perform the SOAP call. @@ -2702,8 +2680,7 @@ func (client *WANIPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNA // Response structure. response := &struct { NewRSIPAvailable string - - NewNATEnabled string + NewNATEnabled string }{} // Perform the SOAP call. @@ -2741,21 +2718,14 @@ func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex u // Response structure. response := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // Perform the SOAP call. @@ -2801,11 +2771,9 @@ func (client *WANIPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex u func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { // Request structure. request := &struct { - NewRemoteHost string - + NewRemoteHost string NewExternalPort string - - NewProtocol string + NewProtocol string }{} // BEGIN Marshal arguments into request. @@ -2822,15 +2790,11 @@ func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string // Response structure. response := &struct { - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // Perform the SOAP call. @@ -2867,21 +2831,14 @@ func (client *WANIPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { // Request structure. request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // BEGIN Marshal arguments into request. @@ -2933,11 +2890,9 @@ func (client *WANIPConnection1) AddPortMapping(NewRemoteHost string, NewExternal func (client *WANIPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { // Request structure. request := &struct { - NewRemoteHost string - + NewRemoteHost string NewExternalPort string - - NewProtocol string + NewProtocol string }{} // BEGIN Marshal arguments into request. @@ -3087,8 +3042,7 @@ func (client *WANIPConnection2) GetConnectionTypeInfo() (NewConnectionType strin // Response structure. response := &struct { - NewConnectionType string - + NewConnectionType string NewPossibleConnectionTypes string }{} @@ -3265,11 +3219,9 @@ func (client *WANIPConnection2) GetStatusInfo() (NewConnectionStatus string, New // Response structure. response := &struct { - NewConnectionStatus string - + NewConnectionStatus string NewLastConnectionError string - - NewUptime string + NewUptime string }{} // Perform the SOAP call. @@ -3380,8 +3332,7 @@ func (client *WANIPConnection2) GetNATRSIPStatus() (NewRSIPAvailable bool, NewNA // Response structure. response := &struct { NewRSIPAvailable string - - NewNATEnabled string + NewNATEnabled string }{} // Perform the SOAP call. @@ -3419,21 +3370,14 @@ func (client *WANIPConnection2) GetGenericPortMappingEntry(NewPortMappingIndex u // Response structure. response := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // Perform the SOAP call. @@ -3479,11 +3423,9 @@ func (client *WANIPConnection2) GetGenericPortMappingEntry(NewPortMappingIndex u func (client *WANIPConnection2) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { // Request structure. request := &struct { - NewRemoteHost string - + NewRemoteHost string NewExternalPort string - - NewProtocol string + NewProtocol string }{} // BEGIN Marshal arguments into request. @@ -3500,15 +3442,11 @@ func (client *WANIPConnection2) GetSpecificPortMappingEntry(NewRemoteHost string // Response structure. response := &struct { - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // Perform the SOAP call. @@ -3545,21 +3483,14 @@ func (client *WANIPConnection2) GetSpecificPortMappingEntry(NewRemoteHost string func (client *WANIPConnection2) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { // Request structure. request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // BEGIN Marshal arguments into request. @@ -3611,11 +3542,9 @@ func (client *WANIPConnection2) AddPortMapping(NewRemoteHost string, NewExternal func (client *WANIPConnection2) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { // Request structure. request := &struct { - NewRemoteHost string - + NewRemoteHost string NewExternalPort string - - NewProtocol string + NewProtocol string }{} // BEGIN Marshal arguments into request. @@ -3653,12 +3582,9 @@ func (client *WANIPConnection2) DeletePortMappingRange(NewStartPort uint16, NewE // Request structure. request := &struct { NewStartPort string - - NewEndPort string - - NewProtocol string - - NewManage string + NewEndPort string + NewProtocol string + NewManage string }{} // BEGIN Marshal arguments into request. @@ -3724,14 +3650,10 @@ func (client *WANIPConnection2) GetExternalIPAddress() (NewExternalIPAddress str func (client *WANIPConnection2) GetListOfPortMappings(NewStartPort uint16, NewEndPort uint16, NewProtocol string, NewManage bool, NewNumberOfPorts uint16) (NewPortListing string, err error) { // Request structure. request := &struct { - NewStartPort string - - NewEndPort string - - NewProtocol string - - NewManage string - + NewStartPort string + NewEndPort string + NewProtocol string + NewManage string NewNumberOfPorts string }{} // BEGIN Marshal arguments into request. @@ -3780,21 +3702,14 @@ func (client *WANIPConnection2) GetListOfPortMappings(NewStartPort uint16, NewEn func (client *WANIPConnection2) AddAnyPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (NewReservedPort uint16, err error) { // Request structure. request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // BEGIN Marshal arguments into request. @@ -3912,8 +3827,7 @@ func (client *WANIPv6FirewallControl1) GetFirewallStatus() (FirewallEnabled bool // Response structure. response := &struct { - FirewallEnabled string - + FirewallEnabled string InboundPinholeAllowed string }{} @@ -3937,15 +3851,11 @@ func (client *WANIPv6FirewallControl1) GetFirewallStatus() (FirewallEnabled bool func (client *WANIPv6FirewallControl1) GetOutboundPinholeTimeout(RemoteHost string, RemotePort uint16, InternalClient string, InternalPort uint16, Protocol uint16) (OutboundPinholeTimeout uint32, err error) { // Request structure. request := &struct { - RemoteHost string - - RemotePort string - + RemoteHost string + RemotePort string InternalClient string - - InternalPort string - - Protocol string + InternalPort string + Protocol string }{} // BEGIN Marshal arguments into request. @@ -3993,17 +3903,12 @@ func (client *WANIPv6FirewallControl1) GetOutboundPinholeTimeout(RemoteHost stri func (client *WANIPv6FirewallControl1) AddPinhole(RemoteHost string, RemotePort uint16, InternalClient string, InternalPort uint16, Protocol uint16, LeaseTime uint32) (UniqueID uint16, err error) { // Request structure. request := &struct { - RemoteHost string - - RemotePort string - + RemoteHost string + RemotePort string InternalClient string - - InternalPort string - - Protocol string - - LeaseTime string + InternalPort string + Protocol string + LeaseTime string }{} // BEGIN Marshal arguments into request. @@ -4054,8 +3959,7 @@ func (client *WANIPv6FirewallControl1) AddPinhole(RemoteHost string, RemotePort func (client *WANIPv6FirewallControl1) UpdatePinhole(UniqueID uint16, NewLeaseTime uint32) (err error) { // Request structure. request := &struct { - UniqueID string - + UniqueID string NewLeaseTime string }{} // BEGIN Marshal arguments into request. @@ -4239,10 +4143,8 @@ func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInf // Request structure. request := &struct { NewISPPhoneNumber string - - NewISPInfo string - - NewLinkType string + NewISPInfo string + NewLinkType string }{} // BEGIN Marshal arguments into request. @@ -4274,8 +4176,7 @@ func (client *WANPOTSLinkConfig1) SetISPInfo(NewISPPhoneNumber string, NewISPInf func (client *WANPOTSLinkConfig1) SetCallRetryInfo(NewNumberOfRetries uint32, NewDelayBetweenRetries uint32) (err error) { // Request structure. request := &struct { - NewNumberOfRetries string - + NewNumberOfRetries string NewDelayBetweenRetries string }{} // BEGIN Marshal arguments into request. @@ -4316,10 +4217,8 @@ func (client *WANPOTSLinkConfig1) GetISPInfo() (NewISPPhoneNumber string, NewISP // Response structure. response := &struct { NewISPPhoneNumber string - - NewISPInfo string - - NewLinkType string + NewISPInfo string + NewLinkType string }{} // Perform the SOAP call. @@ -4351,8 +4250,7 @@ func (client *WANPOTSLinkConfig1) GetCallRetryInfo() (NewNumberOfRetries uint32, // Response structure. response := &struct { - NewNumberOfRetries string - + NewNumberOfRetries string NewDelayBetweenRetries string }{} @@ -4602,8 +4500,7 @@ func (client *WANPPPConnection1) GetConnectionTypeInfo() (NewConnectionType stri // Response structure. response := &struct { - NewConnectionType string - + NewConnectionType string NewPossibleConnectionTypes string }{} @@ -4628,7 +4525,6 @@ func (client *WANPPPConnection1) ConfigureConnection(NewUserName string, NewPass // Request structure. request := &struct { NewUserName string - NewPassword string }{} // BEGIN Marshal arguments into request. @@ -4811,11 +4707,9 @@ func (client *WANPPPConnection1) GetStatusInfo() (NewConnectionStatus string, Ne // Response structure. response := &struct { - NewConnectionStatus string - + NewConnectionStatus string NewLastConnectionError string - - NewUptime string + NewUptime string }{} // Perform the SOAP call. @@ -4847,8 +4741,7 @@ func (client *WANPPPConnection1) GetLinkLayerMaxBitRates() (NewUpstreamMaxBitRat // Response structure. response := &struct { - NewUpstreamMaxBitRate string - + NewUpstreamMaxBitRate string NewDownstreamMaxBitRate string }{} @@ -5087,8 +4980,7 @@ func (client *WANPPPConnection1) GetNATRSIPStatus() (NewRSIPAvailable bool, NewN // Response structure. response := &struct { NewRSIPAvailable string - - NewNATEnabled string + NewNATEnabled string }{} // Perform the SOAP call. @@ -5126,21 +5018,14 @@ func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex // Response structure. response := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // Perform the SOAP call. @@ -5186,11 +5071,9 @@ func (client *WANPPPConnection1) GetGenericPortMappingEntry(NewPortMappingIndex func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32, err error) { // Request structure. request := &struct { - NewRemoteHost string - + NewRemoteHost string NewExternalPort string - - NewProtocol string + NewProtocol string }{} // BEGIN Marshal arguments into request. @@ -5207,15 +5090,11 @@ func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost strin // Response structure. response := &struct { - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // Perform the SOAP call. @@ -5252,21 +5131,14 @@ func (client *WANPPPConnection1) GetSpecificPortMappingEntry(NewRemoteHost strin func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string, NewInternalPort uint16, NewInternalClient string, NewEnabled bool, NewPortMappingDescription string, NewLeaseDuration uint32) (err error) { // Request structure. request := &struct { - NewRemoteHost string - - NewExternalPort string - - NewProtocol string - - NewInternalPort string - - NewInternalClient string - - NewEnabled string - + NewRemoteHost string + NewExternalPort string + NewProtocol string + NewInternalPort string + NewInternalClient string + NewEnabled string NewPortMappingDescription string - - NewLeaseDuration string + NewLeaseDuration string }{} // BEGIN Marshal arguments into request. @@ -5318,11 +5190,9 @@ func (client *WANPPPConnection1) AddPortMapping(NewRemoteHost string, NewExterna func (client *WANPPPConnection1) DeletePortMapping(NewRemoteHost string, NewExternalPort uint16, NewProtocol string) (err error) { // Request structure. request := &struct { - NewRemoteHost string - + NewRemoteHost string NewExternalPort string - - NewProtocol string + NewProtocol string }{} // BEGIN Marshal arguments into request. diff --git a/vendor/github.com/huin/goupnp/device.go b/vendor/github.com/huin/goupnp/device.go index e5b658b21a..567ab4cfef 100644 --- a/vendor/github.com/huin/goupnp/device.go +++ b/vendor/github.com/huin/goupnp/device.go @@ -147,9 +147,9 @@ func (srv *Service) String() string { return fmt.Sprintf("Service ID %s : %s", srv.ServiceId, srv.ServiceType) } -// RequestSCDP requests the SCPD (soap actions and state variables description) +// RequestSCPD requests the SCPD (soap actions and state variables description) // for the service. -func (srv *Service) RequestSCDP() (*scpd.SCPD, error) { +func (srv *Service) RequestSCPD() (*scpd.SCPD, error) { if !srv.SCPDURL.Ok { return nil, errors.New("bad/missing SCPD URL, or no URLBase has been set") } @@ -160,6 +160,12 @@ func (srv *Service) RequestSCDP() (*scpd.SCPD, error) { return s, nil } +// RequestSCDP is for compatibility only, prefer RequestSCPD. This was a +// misspelling of RequestSCDP. +func (srv *Service) RequestSCDP() (*scpd.SCPD, error) { + return srv.RequestSCPD() +} + func (srv *Service) NewSOAPClient() *soap.SOAPClient { return soap.NewSOAPClient(srv.ControlURL.URL) } diff --git a/vendor/github.com/huin/goupnp/httpu/httpu.go b/vendor/github.com/huin/goupnp/httpu/httpu.go index f52dad68b1..44b0c583ca 100644 --- a/vendor/github.com/huin/goupnp/httpu/httpu.go +++ b/vendor/github.com/huin/goupnp/httpu/httpu.go @@ -122,11 +122,13 @@ func (httpu *HTTPUClient) Do(req *http.Request, timeout time.Duration, numSends // Parse response. response, err := http.ReadResponse(bufio.NewReader(bytes.NewBuffer(responseBytes[:n])), req) if err != nil { - log.Print("httpu: error while parsing response: %v", err) + log.Printf("httpu: error while parsing response: %v", err) continue } responses = append(responses, response) } - return responses, err + + // Timeout reached - return discovered responses. + return responses, nil } diff --git a/vendor/github.com/huin/goupnp/soap/soap.go b/vendor/github.com/huin/goupnp/soap/soap.go index 815610734c..29e89f2a92 100644 --- a/vendor/github.com/huin/goupnp/soap/soap.go +++ b/vendor/github.com/huin/goupnp/soap/soap.go @@ -10,6 +10,7 @@ import ( "net/http" "net/url" "reflect" + "regexp" ) const ( @@ -126,14 +127,49 @@ func encodeRequestArgs(w *bytes.Buffer, inAction interface{}) error { if value.Kind() != reflect.String { return fmt.Errorf("goupnp: SOAP arg %q is not of type string, but of type %v", argName, value.Type()) } - if err := enc.EncodeElement(value.Interface(), xml.StartElement{xml.Name{"", argName}, nil}); err != nil { - return fmt.Errorf("goupnp: error encoding SOAP arg %q: %v", argName, err) + elem := xml.StartElement{xml.Name{"", argName}, nil} + if err := enc.EncodeToken(elem); err != nil { + return fmt.Errorf("goupnp: error encoding start element for SOAP arg %q: %v", argName, err) + } + if err := enc.Flush(); err != nil { + return fmt.Errorf("goupnp: error flushing start element for SOAP arg %q: %v", argName, err) + } + if _, err := w.Write([]byte(escapeXMLText(value.Interface().(string)))); err != nil { + return fmt.Errorf("goupnp: error writing value for SOAP arg %q: %v", argName, err) + } + if err := enc.EncodeToken(elem.End()); err != nil { + return fmt.Errorf("goupnp: error encoding end element for SOAP arg %q: %v", argName, err) } } enc.Flush() return nil } +var xmlCharRx = regexp.MustCompile("[<>&]") + +// escapeXMLText is used by generated code to escape text in XML, but only +// escaping the characters `<`, `>`, and `&`. +// +// This is provided in order to work around SOAP server implementations that +// fail to decode XML correctly, specifically failing to decode `"`, `'`. Note +// that this can only be safely used for injecting into XML text, but not into +// attributes or other contexts. +func escapeXMLText(s string) string { + return xmlCharRx.ReplaceAllStringFunc(s, replaceEntity) +} + +func replaceEntity(s string) string { + switch s { + case "<": + return "<" + case ">": + return ">" + case "&": + return "&" + } + return s +} + type soapEnvelope struct { XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` EncodingStyle string `xml:"http://schemas.xmlsoap.org/soap/envelope/ encodingStyle,attr"` diff --git a/vendor/github.com/huin/goupnp/soap/types.go b/vendor/github.com/huin/goupnp/soap/types.go index fdbeec8d42..3e73d99d92 100644 --- a/vendor/github.com/huin/goupnp/soap/types.go +++ b/vendor/github.com/huin/goupnp/soap/types.go @@ -47,6 +47,15 @@ func UnmarshalUi4(s string) (uint32, error) { return uint32(v), err } +func MarshalUi8(v uint64) (string, error) { + return strconv.FormatUint(v, 10), nil +} + +func UnmarshalUi8(s string) (uint64, error) { + v, err := strconv.ParseUint(s, 10, 64) + return uint64(v), err +} + func MarshalI1(v int8) (string, error) { return strconv.FormatInt(int64(v), 10), nil } @@ -325,7 +334,7 @@ func UnmarshalTimeOfDay(s string) (TimeOfDay, error) { if err != nil { return TimeOfDay{}, err } else if t.HasOffset { - return TimeOfDay{}, fmt.Errorf("soap time: value %q contains unexpected timezone") + return TimeOfDay{}, fmt.Errorf("soap time: value %q contains unexpected timezone", s) } return t, nil } diff --git a/vendor/github.com/huin/goupnp/ssdp/ssdp.go b/vendor/github.com/huin/goupnp/ssdp/ssdp.go index 8178f5d948..4c03b25565 100644 --- a/vendor/github.com/huin/goupnp/ssdp/ssdp.go +++ b/vendor/github.com/huin/goupnp/ssdp/ssdp.go @@ -20,6 +20,11 @@ const ( ssdpSearchPort = 1900 methodSearch = "M-SEARCH" methodNotify = "NOTIFY" + + // SSDPAll is a value for searchTarget that searches for all devices and services. + SSDPAll = "ssdp:all" + // UPNPRootDevice is a value for searchTarget that searches for all root devices. + UPNPRootDevice = "upnp:rootdevice" ) // SSDPRawSearch performs a fairly raw SSDP search request, and returns the @@ -54,13 +59,15 @@ func SSDPRawSearch(httpu *httpu.HTTPUClient, searchTarget string, maxWaitSeconds if err != nil { return nil, err } + + isExactSearch := searchTarget != SSDPAll && searchTarget != UPNPRootDevice + for _, response := range allResponses { if response.StatusCode != 200 { log.Printf("ssdp: got response status code %q in search response", response.Status) continue } - if st := response.Header.Get("ST"); st != searchTarget { - log.Printf("ssdp: got unexpected search target result %q", st) + if st := response.Header.Get("ST"); isExactSearch && st != searchTarget { continue } location, err := response.Location() diff --git a/vendor/github.com/influxdata/influxdb/LICENSE b/vendor/github.com/influxdata/influxdb/LICENSE index 63cef79ba6..2517ee1da6 100644 --- a/vendor/github.com/influxdata/influxdb/LICENSE +++ b/vendor/github.com/influxdata/influxdb/LICENSE @@ -1,20 +1,21 @@ -The MIT License (MIT) +MIT License -Copyright (c) 2013-2016 Errplane Inc. +Copyright (c) 2018 InfluxData -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/influxdata/influxdb/models/consistency.go b/vendor/github.com/influxdata/influxdb/models/consistency.go deleted file mode 100644 index 2a3269bca1..0000000000 --- a/vendor/github.com/influxdata/influxdb/models/consistency.go +++ /dev/null @@ -1,48 +0,0 @@ -package models - -import ( - "errors" - "strings" -) - -// ConsistencyLevel represent a required replication criteria before a write can -// be returned as successful. -// -// The consistency level is handled in open-source InfluxDB but only applicable to clusters. -type ConsistencyLevel int - -const ( - // ConsistencyLevelAny allows for hinted handoff, potentially no write happened yet. - ConsistencyLevelAny ConsistencyLevel = iota - - // ConsistencyLevelOne requires at least one data node acknowledged a write. - ConsistencyLevelOne - - // ConsistencyLevelQuorum requires a quorum of data nodes to acknowledge a write. - ConsistencyLevelQuorum - - // ConsistencyLevelAll requires all data nodes to acknowledge a write. - ConsistencyLevelAll -) - -var ( - // ErrInvalidConsistencyLevel is returned when parsing the string version - // of a consistency level. - ErrInvalidConsistencyLevel = errors.New("invalid consistency level") -) - -// ParseConsistencyLevel converts a consistency level string to the corresponding ConsistencyLevel const. -func ParseConsistencyLevel(level string) (ConsistencyLevel, error) { - switch strings.ToLower(level) { - case "any": - return ConsistencyLevelAny, nil - case "one": - return ConsistencyLevelOne, nil - case "quorum": - return ConsistencyLevelQuorum, nil - case "all": - return ConsistencyLevelAll, nil - default: - return 0, ErrInvalidConsistencyLevel - } -} diff --git a/vendor/github.com/influxdata/influxdb/models/points.go b/vendor/github.com/influxdata/influxdb/models/points.go index ad80a816bf..a3b2c47c6c 100644 --- a/vendor/github.com/influxdata/influxdb/models/points.go +++ b/vendor/github.com/influxdata/influxdb/models/points.go @@ -12,20 +12,39 @@ import ( "strconv" "strings" "time" + "unicode" + "unicode/utf8" "github.com/influxdata/influxdb/pkg/escape" ) +// Values used to store the field key and measurement name as special internal tags. +const ( + FieldKeyTagKey = "\xff" + MeasurementTagKey = "\x00" +) + +// Predefined byte representations of special tag keys. var ( - measurementEscapeCodes = map[byte][]byte{ - ',': []byte(`\,`), - ' ': []byte(`\ `), + FieldKeyTagKeyBytes = []byte(FieldKeyTagKey) + MeasurementTagKeyBytes = []byte(MeasurementTagKey) +) + +type escapeSet struct { + k [1]byte + esc [2]byte +} + +var ( + measurementEscapeCodes = [...]escapeSet{ + {k: [1]byte{','}, esc: [2]byte{'\\', ','}}, + {k: [1]byte{' '}, esc: [2]byte{'\\', ' '}}, } - tagEscapeCodes = map[byte][]byte{ - ',': []byte(`\,`), - ' ': []byte(`\ `), - '=': []byte(`\=`), + tagEscapeCodes = [...]escapeSet{ + {k: [1]byte{','}, esc: [2]byte{'\\', ','}}, + {k: [1]byte{' '}, esc: [2]byte{'\\', ' '}}, + {k: [1]byte{'='}, esc: [2]byte{'\\', '='}}, } // ErrPointMustHaveAField is returned when operating on a point that does not have any fields. @@ -64,6 +83,9 @@ type Point interface { // Tags returns the tag set for the point. Tags() Tags + // ForEachTag iterates over each tag invoking fn. If fn return false, iteration stops. + ForEachTag(fn func(k, v []byte) bool) + // AddTag adds or replaces a tag value for a point. AddTag(key, value string) @@ -124,7 +146,7 @@ type Point interface { // the result, potentially reducing string allocations. AppendString(buf []byte) []byte - // FieldIterator retuns a FieldIterator that can be used to traverse the + // FieldIterator returns a FieldIterator that can be used to traverse the // fields of a point without constructing the in-memory map. FieldIterator() FieldIterator } @@ -152,6 +174,23 @@ const ( Unsigned ) +func (t FieldType) String() string { + switch t { + case Integer: + return "Integer" + case Float: + return "Float" + case Boolean: + return "Boolean" + case String: + return "String" + case Empty: + return "Empty" + default: + return "" + } +} + // FieldIterator provides a low-allocation interface to iterate through a point's fields. type FieldIterator interface { // Next indicates whether there any fields remaining. @@ -249,13 +288,17 @@ const ( // ParsePoints returns a slice of Points from a text representation of a point // with each point separated by newlines. If any points fail to parse, a non-nil error // will be returned in addition to the points that parsed successfully. -func ParsePoints(buf []byte) ([]Point, error) { - return ParsePointsWithPrecision(buf, time.Now().UTC(), "n") +// +// The mm argument supplies the new measurement which is generated by calling +// EscapeMeasurement(EncodeName(orgID, bucketID)). The existing measurement is +// moved to the "_m" tag. +func ParsePoints(buf, mm []byte) ([]Point, error) { + return ParsePointsWithPrecision(buf, mm, time.Now().UTC(), "n") } // ParsePointsString is identical to ParsePoints but accepts a string. -func ParsePointsString(buf string) ([]Point, error) { - return ParsePoints([]byte(buf)) +func ParsePointsString(buf, mm string) ([]Point, error) { + return ParsePoints([]byte(buf), []byte(mm)) } // ParseKey returns the measurement name and tags from a point. @@ -263,36 +306,66 @@ func ParsePointsString(buf string) ([]Point, error) { // NOTE: to minimize heap allocations, the returned Tags will refer to subslices of buf. // This can have the unintended effect preventing buf from being garbage collected. func ParseKey(buf []byte) (string, Tags) { - meas, tags := ParseKeyBytes(buf) - return string(meas), tags + name, tags := ParseKeyBytes(buf) + return string(name), tags } func ParseKeyBytes(buf []byte) ([]byte, Tags) { + return ParseKeyBytesWithTags(buf, nil) +} + +func ParseKeyBytesWithTags(buf []byte, tags Tags) ([]byte, Tags) { // Ignore the error because scanMeasurement returns "missing fields" which we ignore // when just parsing a key state, i, _ := scanMeasurement(buf, 0) - var tags Tags + var name []byte if state == tagKeyState { - tags = parseTags(buf) + tags = parseTags(buf, tags) // scanMeasurement returns the location of the comma if there are tags, strip that off - return buf[:i-1], tags + name = buf[:i-1] + } else { + name = buf[:i] } - return buf[:i], tags + return UnescapeMeasurement(name), tags } func ParseTags(buf []byte) Tags { - return parseTags(buf) + return parseTags(buf, nil) } -func ParseName(buf []byte) ([]byte, error) { +func ParseTagsWithTags(buf []byte, tags Tags) Tags { + return parseTags(buf, tags) +} + +func ParseName(buf []byte) []byte { // Ignore the error because scanMeasurement returns "missing fields" which we ignore // when just parsing a key state, i, _ := scanMeasurement(buf, 0) + var name []byte if state == tagKeyState { - return buf[:i-1], nil + name = buf[:i-1] + } else { + name = buf[:i] } - return buf[:i], nil + + return UnescapeMeasurement(name) +} + +// ValidPrecision checks if the precision is known. +func ValidPrecision(precision string) bool { + switch precision { + case "ns", "us", "ms", "s": + return true + default: + return false + } +} + +// ParsePointsWithPrecisionV1 is similar to ParsePointsWithPrecision but does +// not rewrite the measurement & field keys. +func ParsePointsWithPrecisionV1(buf []byte, mm []byte, defaultTime time.Time, precision string) (_ []Point, err error) { + return parsePointsWithPrecision(buf, mm, defaultTime, precision, false) } // ParsePointsWithPrecision is similar to ParsePoints, but allows the @@ -300,7 +373,11 @@ func ParseName(buf []byte) ([]byte, error) { // // NOTE: to minimize heap allocations, the returned Points will refer to subslices of buf. // This can have the unintended effect preventing buf from being garbage collected. -func ParsePointsWithPrecision(buf []byte, defaultTime time.Time, precision string) ([]Point, error) { +func ParsePointsWithPrecision(buf []byte, mm []byte, defaultTime time.Time, precision string) (_ []Point, err error) { + return parsePointsWithPrecision(buf, mm, defaultTime, precision, true) +} + +func parsePointsWithPrecision(buf []byte, mm []byte, defaultTime time.Time, precision string, rewrite bool) (_ []Point, err error) { points := make([]Point, 0, bytes.Count(buf, []byte{'\n'})+1) var ( pos int @@ -332,22 +409,19 @@ func ParsePointsWithPrecision(buf []byte, defaultTime time.Time, precision strin block = block[:len(block)-1] } - pt, err := parsePoint(block[start:], defaultTime, precision) + points, err = parsePointsAppend(points, block[start:], mm, defaultTime, precision, rewrite) if err != nil { failed = append(failed, fmt.Sprintf("unable to parse '%s': %v", string(block[start:]), err)) - } else { - points = append(points, pt) } - } if len(failed) > 0 { return points, fmt.Errorf("%s", strings.Join(failed, "\n")) } - return points, nil + return points, nil } -func parsePoint(buf []byte, defaultTime time.Time, precision string) (Point, error) { +func parsePointsAppend(points []Point, buf []byte, mm []byte, defaultTime time.Time, precision string, rewrite bool) ([]Point, error) { // scan the first block which is measurement[,tag1=value1,tag2=value=2...] pos, key, err := scanKey(buf, 0) if err != nil { @@ -356,48 +430,43 @@ func parsePoint(buf []byte, defaultTime time.Time, precision string) (Point, err // measurement name is required if len(key) == 0 { - return nil, fmt.Errorf("missing measurement") + return points, fmt.Errorf("missing measurement") } if len(key) > MaxKeyLength { - return nil, fmt.Errorf("max key length exceeded: %v > %v", len(key), MaxKeyLength) + return points, fmt.Errorf("max key length exceeded: %v > %v", len(key), MaxKeyLength) + } + + // Since the measurement is converted to a tag and measurements & tags have + // different escaping rules, we need to check if the measurement needs escaping. + _, i, _ := scanMeasurement(key, 0) + keyMeasurement := key[:i-1] + if rewrite && bytes.IndexByte(keyMeasurement, '=') != -1 { + escapedKeyMeasurement := bytes.Replace(keyMeasurement, []byte("="), []byte(`\=`), -1) + + newKey := make([]byte, len(escapedKeyMeasurement)+(len(key)-len(keyMeasurement))) + copy(newKey, escapedKeyMeasurement) + copy(newKey[len(escapedKeyMeasurement):], key[len(keyMeasurement):]) + key = newKey } // scan the second block is which is field1=value1[,field2=value2,...] + // at least one field is required pos, fields, err := scanFields(buf, pos) if err != nil { - return nil, err - } - - // at least one field is required - if len(fields) == 0 { - return nil, fmt.Errorf("missing fields") - } - - var maxKeyErr error - walkFields(fields, func(k, v []byte) bool { - if sz := seriesKeySize(key, k); sz > MaxKeyLength { - maxKeyErr = fmt.Errorf("max key length exceeded: %v > %v", sz, MaxKeyLength) - return false - } - return true - }) - - if maxKeyErr != nil { - return nil, maxKeyErr + return points, err + } else if len(fields) == 0 { + return points, fmt.Errorf("missing fields") } // scan the last block which is an optional integer timestamp pos, ts, err := scanTime(buf, pos) if err != nil { - return nil, err + return points, err } - pt := &point{ - key: key, - fields: fields, - ts: ts, - } + // Build point with timestamp only. + pt := point{ts: ts} if len(ts) == 0 { pt.time = defaultTime @@ -405,39 +474,80 @@ func parsePoint(buf []byte, defaultTime time.Time, precision string) (Point, err } else { ts, err := parseIntBytes(ts, 10, 64) if err != nil { - return nil, err + return points, err } pt.time, err = SafeCalcTime(ts, precision) if err != nil { - return nil, err + return points, err } // Determine if there are illegal non-whitespace characters after the // timestamp block. for pos < len(buf) { if buf[pos] != ' ' { - return nil, ErrInvalidPoint + return points, ErrInvalidPoint } pos++ } } - return pt, nil + + // Loop over fields and split points while validating field. + var maxKeyErr error + if err := walkFields(fields, func(k, v, fieldBuf []byte) bool { + newKey := key + + // Build new key with measurement & field as keys. + if rewrite { + newKey = newV2Key(key, mm, k) + if sz := seriesKeySizeV2(key, mm, k); sz > MaxKeyLength { + maxKeyErr = fmt.Errorf("max key length exceeded: %v > %v", sz, MaxKeyLength) + return false + } + } + + other := pt + other.key = newKey + other.fields = fieldBuf + points = append(points, &other) + + return true + }); err != nil { + return points, err + } else if maxKeyErr != nil { + return points, maxKeyErr + } + + return points, nil +} + +// newV2Key returns a new key by converting the old measurement & field into keys. +func newV2Key(oldKey, mm, field []byte) []byte { + newKey := make([]byte, len(mm)+1+len(MeasurementTagKey)+1+len(oldKey)+1+len(FieldKeyTagKey)+1+len(field)) + buf := newKey + + copy(buf, mm) + buf = buf[len(mm):] + + buf[0], buf[1], buf[2], buf = ',', MeasurementTagKeyBytes[0], '=', buf[3:] + copy(buf, oldKey) + buf = buf[len(oldKey):] + + buf[0], buf[1], buf[2], buf = ',', FieldKeyTagKeyBytes[0], '=', buf[3:] + copy(buf, field) + + return newKey } // GetPrecisionMultiplier will return a multiplier for the precision specified. func GetPrecisionMultiplier(precision string) int64 { d := time.Nanosecond switch precision { - case "u": + case "us": d = time.Microsecond case "ms": d = time.Millisecond case "s": d = time.Second - case "m": - d = time.Minute - case "h": - d = time.Hour } return int64(d) } @@ -1199,23 +1309,33 @@ func scanFieldValue(buf []byte, i int) (int, []byte) { } func EscapeMeasurement(in []byte) []byte { - for b, esc := range measurementEscapeCodes { - in = bytes.Replace(in, []byte{b}, esc, -1) + for _, c := range measurementEscapeCodes { + if bytes.IndexByte(in, c.k[0]) != -1 { + in = bytes.Replace(in, c.k[:], c.esc[:], -1) + } } return in } -func unescapeMeasurement(in []byte) []byte { - for b, esc := range measurementEscapeCodes { - in = bytes.Replace(in, esc, []byte{b}, -1) +func UnescapeMeasurement(in []byte) []byte { + if bytes.IndexByte(in, '\\') == -1 { + return in + } + + for i := range measurementEscapeCodes { + c := &measurementEscapeCodes[i] + if bytes.IndexByte(in, c.k[0]) != -1 { + in = bytes.Replace(in, c.esc[:], c.k[:], -1) + } } return in } func escapeTag(in []byte) []byte { - for b, esc := range tagEscapeCodes { - if bytes.IndexByte(in, b) != -1 { - in = bytes.Replace(in, []byte{b}, esc, -1) + for i := range tagEscapeCodes { + c := &tagEscapeCodes[i] + if bytes.IndexByte(in, c.k[0]) != -1 { + in = bytes.Replace(in, c.k[:], c.esc[:], -1) } } return in @@ -1226,9 +1346,10 @@ func unescapeTag(in []byte) []byte { return in } - for b, esc := range tagEscapeCodes { - if bytes.IndexByte(in, b) != -1 { - in = bytes.Replace(in, esc, []byte{b}, -1) + for i := range tagEscapeCodes { + c := &tagEscapeCodes[i] + if bytes.IndexByte(in, c.k[0]) != -1 { + in = bytes.Replace(in, c.esc[:], c.k[:], -1) } } return in @@ -1280,7 +1401,8 @@ func unescapeStringField(in string) string { } // NewPoint returns a new point with the given measurement name, tags, fields and timestamp. If -// an unsupported field value (NaN) or out of range time is passed, this function returns an error. +// an unsupported field value (NaN, or +/-Inf) or out of range time is passed, this function +// returns an error. func NewPoint(name string, tags Tags, fields Fields, t time.Time) (Point, error) { key, err := pointKey(name, tags, fields, t) if err != nil { @@ -1294,6 +1416,15 @@ func NewPoint(name string, tags Tags, fields Fields, t time.Time) (Point, error) }, nil } +// NewPointFromSeries returns a Point given the serialized key, some fields, and a time. +func NewPointFromSeries(key []byte, fields Fields, t time.Time) Point { + return &point{ + key: key, + time: t, + fields: fields.MarshalBinary(), + } +} + // pointKey checks some basic requirements for valid points, and returns the // key, along with an possible error. func pointKey(measurement string, tags Tags, fields Fields, t time.Time) ([]byte, error) { @@ -1311,13 +1442,19 @@ func pointKey(measurement string, tags Tags, fields Fields, t time.Time) ([]byte switch value := value.(type) { case float64: // Ensure the caller validates and handles invalid field values + if math.IsInf(value, 0) { + return nil, fmt.Errorf("+/-Inf is an unsupported value for field %s", key) + } if math.IsNaN(value) { - return nil, fmt.Errorf("NaN is an unsupported value for field %s", key) + return nil, fmt.Errorf("NAN is an unsupported value for field %s", key) } case float32: // Ensure the caller validates and handles invalid field values + if math.IsInf(float64(value), 0) { + return nil, fmt.Errorf("+/-Inf is an unsupported value for field %s", key) + } if math.IsNaN(float64(value)) { - return nil, fmt.Errorf("NaN is an unsupported value for field %s", key) + return nil, fmt.Errorf("NAN is an unsupported value for field %s", key) } } if len(key) == 0 { @@ -1327,7 +1464,7 @@ func pointKey(measurement string, tags Tags, fields Fields, t time.Time) ([]byte key := MakeKey([]byte(measurement), tags) for field := range fields { - sz := seriesKeySize(key, []byte(field)) + sz := seriesKeySizeV1(key, []byte(field)) if sz > MaxKeyLength { return nil, fmt.Errorf("max key length exceeded: %v > %v", sz, MaxKeyLength) } @@ -1336,10 +1473,12 @@ func pointKey(measurement string, tags Tags, fields Fields, t time.Time) ([]byte return key, nil } -func seriesKeySize(key, field []byte) int { - // 4 is the length of the tsm1.fieldKeySeparator constant. It's inlined here to avoid a circular - // dependency. - return len(key) + 4 + len(field) +func seriesKeySizeV1(key, field []byte) int { + return len(key) + len("#!~#") + len(field) +} + +func seriesKeySizeV2(key, mm, field []byte) int { + return len(mm) + len(",\xFF=") + len(field) + len(",\x00=") + len(key) + len("#!~#") + len(field) } // NewPointFromBytes returns a new Point from a marshalled Point. @@ -1441,10 +1580,14 @@ func (p *point) Tags() Tags { if p.cachedTags != nil { return p.cachedTags } - p.cachedTags = parseTags(p.key) + p.cachedTags = parseTags(p.key, nil) return p.cachedTags } +func (p *point) ForEachTag(fn func(k, v []byte) bool) { + walkTags(p.key, fn) +} + func (p *point) HasTag(tag []byte) bool { if len(p.key) == 0 { return false @@ -1504,15 +1647,20 @@ func walkTags(buf []byte, fn func(key, value []byte) bool) { // walkFields walks each field key and value via fn. If fn returns false, the iteration // is stopped. The values are the raw byte slices and not the converted types. -func walkFields(buf []byte, fn func(key, value []byte) bool) { +func walkFields(buf []byte, fn func(key, value, data []byte) bool) error { var i int var key, val []byte for len(buf) > 0 { + data := buf + i, key = scanTo(buf, 0, '=') + if i > len(buf)-2 { + return fmt.Errorf("invalid value: field-key=%s", key) + } buf = buf[i+1:] i, val = scanFieldValue(buf, 0) buf = buf[i:] - if !fn(key, val) { + if !fn(key, val, data[:len(data)-len(buf)]) { break } @@ -1521,29 +1669,52 @@ func walkFields(buf []byte, fn func(key, value []byte) bool) { buf = buf[1:] } } + return nil } -func parseTags(buf []byte) Tags { +// parseTags parses buf into the provided destination tags, returning destination +// Tags, which may have a different length and capacity. +func parseTags(buf []byte, dst Tags) Tags { if len(buf) == 0 { return nil } - tags := make(Tags, bytes.Count(buf, []byte(","))) - p := 0 + n := bytes.Count(buf, []byte(",")) + if cap(dst) < n { + dst = make(Tags, n) + } else { + dst = dst[:n] + } + + // Ensure existing behaviour when point has no tags and nil slice passed in. + if dst == nil { + dst = Tags{} + } + + // Series keys can contain escaped commas, therefore the number of commas + // in a series key only gives an estimation of the upper bound on the number + // of tags. + var i int walkTags(buf, func(key, value []byte) bool { - tags[p].Key = key - tags[p].Value = value - p++ + dst[i].Key, dst[i].Value = key, value + i++ return true }) - return tags + return dst[:i] } // MakeKey creates a key for a set of tags. func MakeKey(name []byte, tags Tags) []byte { + return AppendMakeKey(nil, name, tags) +} + +// AppendMakeKey appends the key derived from name and tags to dst and returns the extended buffer. +func AppendMakeKey(dst []byte, name []byte, tags Tags) []byte { // unescape the name and then re-escape it to avoid double escaping. // The key should always be stored in escaped form. - return append(EscapeMeasurement(unescapeMeasurement(name)), tags.HashKey()...) + dst = append(dst, EscapeMeasurement(UnescapeMeasurement(name))...) + dst = tags.AppendHashKey(dst) + return dst } // SetTags replaces the tags for the point. @@ -1577,17 +1748,12 @@ func (p *point) Fields() (Fields, error) { // SetPrecision will round a time to the specified precision. func (p *point) SetPrecision(precision string) { switch precision { - case "n": - case "u": + case "us": p.SetTime(p.Time().Truncate(time.Microsecond)) case "ms": p.SetTime(p.Time().Truncate(time.Millisecond)) case "s": p.SetTime(p.Time().Truncate(time.Second)) - case "m": - p.SetTime(p.Time().Truncate(time.Minute)) - case "h": - p.SetTime(p.Time().Truncate(time.Hour)) } } @@ -1692,10 +1858,7 @@ func (p *point) UnmarshalBinary(b []byte) error { p.fields, b = b[:n], b[n:] // Read timestamp. - if err := p.time.UnmarshalBinary(b); err != nil { - return err - } - return nil + return p.time.UnmarshalBinary(b) } // PrecisionString returns a string representation of the point. If there @@ -1914,8 +2077,8 @@ func (a Tags) String() string { // for data structures or delimiters for example. func (a Tags) Size() int { var total int - for _, t := range a { - total += t.Size() + for i := range a { + total += a[i].Size() } return total } @@ -2048,42 +2211,78 @@ func (a Tags) Merge(other map[string]string) Tags { // HashKey hashes all of a tag's keys. func (a Tags) HashKey() []byte { + return a.AppendHashKey(nil) +} + +func (a Tags) needsEscape() bool { + for i := range a { + t := &a[i] + for j := range tagEscapeCodes { + c := &tagEscapeCodes[j] + if bytes.IndexByte(t.Key, c.k[0]) != -1 || bytes.IndexByte(t.Value, c.k[0]) != -1 { + return true + } + } + } + return false +} + +// AppendHashKey appends the result of hashing all of a tag's keys and values to dst and returns the extended buffer. +func (a Tags) AppendHashKey(dst []byte) []byte { // Empty maps marshal to empty bytes. if len(a) == 0 { - return nil + return dst } // Type invariant: Tags are sorted - escaped := make(Tags, 0, len(a)) sz := 0 - for _, t := range a { - ek := escapeTag(t.Key) - ev := escapeTag(t.Value) - - if len(ev) > 0 { - escaped = append(escaped, Tag{Key: ek, Value: ev}) - sz += len(ek) + len(ev) + var escaped Tags + if a.needsEscape() { + var tmp [20]Tag + if len(a) < len(tmp) { + escaped = tmp[:len(a)] + } else { + escaped = make(Tags, len(a)) } + + for i := range a { + t := &a[i] + nt := &escaped[i] + nt.Key = escapeTag(t.Key) + nt.Value = escapeTag(t.Value) + sz += len(nt.Key) + len(nt.Value) + } + } else { + sz = a.Size() + escaped = a } sz += len(escaped) + (len(escaped) * 2) // separators // Generate marshaled bytes. - b := make([]byte, sz) - buf := b + if cap(dst)-len(dst) < sz { + nd := make([]byte, len(dst), len(dst)+sz) + copy(nd, dst) + dst = nd + } + buf := dst[len(dst) : len(dst)+sz] idx := 0 - for _, k := range escaped { + for i := range escaped { + k := &escaped[i] + if len(k.Value) == 0 { + continue + } buf[idx] = ',' idx++ - copy(buf[idx:idx+len(k.Key)], k.Key) + copy(buf[idx:], k.Key) idx += len(k.Key) buf[idx] = '=' idx++ - copy(buf[idx:idx+len(k.Value)], k.Value) + copy(buf[idx:], k.Value) idx += len(k.Value) } - return b[:idx] + return dst[:len(dst)+idx] } // CopyTags returns a shallow copy of tags. @@ -2121,7 +2320,7 @@ func DeepCopyTags(a Tags) Tags { // values. type Fields map[string]interface{} -// FieldIterator retuns a FieldIterator that can be used to traverse the +// FieldIterator returns a FieldIterator that can be used to traverse the // fields of a point without constructing the in-memory map. func (p *point) FieldIterator() FieldIterator { p.Reset() @@ -2242,7 +2441,7 @@ func (p *point) Reset() { } // MarshalBinary encodes all the fields to their proper type and returns the binary -// represenation +// representation // NOTE: uint64 is specifically not supported due to potential overflow when we decode // again later to an int64 // NOTE2: uint is accepted, and may be 64 bits, and is for some reason accepted... @@ -2330,8 +2529,37 @@ func appendField(b []byte, k string, v interface{}) []byte { return b } -type byteSlices [][]byte +// ValidToken returns true if the provided token is a valid unicode string, and +// only contains printable, non-replacement characters. +func ValidToken(a []byte) bool { + if !utf8.Valid(a) { + return false + } -func (a byteSlices) Len() int { return len(a) } -func (a byteSlices) Less(i, j int) bool { return bytes.Compare(a[i], a[j]) == -1 } -func (a byteSlices) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + for _, r := range string(a) { + if !unicode.IsPrint(r) || r == unicode.ReplacementChar { + return false + } + } + return true +} + +// ValidTagTokens returns true if all the provided tag key and values are +// valid. +// +// ValidTagTokens does not validate the special tag keys used to represent the +// measurement name and field key, but it does validate the associated values. +func ValidTagTokens(tags Tags) bool { + for _, tag := range tags { + // Validate all external tag keys. + if !bytes.Equal(tag.Key, MeasurementTagKeyBytes) && !bytes.Equal(tag.Key, FieldKeyTagKeyBytes) && !ValidToken(tag.Key) { + return false + } + + // Validate all tag values (this will also validate the field key, which is a tag value for the special field key tag key). + if !ValidToken(tag.Value) { + return false + } + } + return true +} diff --git a/vendor/github.com/influxdata/influxdb/models/time.go b/vendor/github.com/influxdata/influxdb/models/time.go index e98f2cb336..297892c6da 100644 --- a/vendor/github.com/influxdata/influxdb/models/time.go +++ b/vendor/github.com/influxdata/influxdb/models/time.go @@ -10,7 +10,7 @@ import ( ) const ( - // MinNanoTime is the minumum time that can be represented. + // MinNanoTime is the minimum time that can be represented. // // 1677-09-21 00:12:43.145224194 +0000 UTC // diff --git a/vendor/github.com/jackpal/go-nat-pmp/README.md b/vendor/github.com/jackpal/go-nat-pmp/README.md index 3ca687f0b7..54da942d31 100644 --- a/vendor/github.com/jackpal/go-nat-pmp/README.md +++ b/vendor/github.com/jackpal/go-nat-pmp/README.md @@ -6,7 +6,7 @@ IP address of a firewall. NAT-PMP is supported by Apple brand routers and open source routers like Tomato and DD-WRT. -See http://tools.ietf.org/html/draft-cheshire-nat-pmp-03 +See https://tools.ietf.org/rfc/rfc6886.txt [![Build Status](https://travis-ci.org/jackpal/go-nat-pmp.svg)](https://travis-ci.org/jackpal/go-nat-pmp) @@ -20,11 +20,12 @@ Usage ----- import ( + "fmt" "github.com/jackpal/gateway" natpmp "github.com/jackpal/go-nat-pmp" ) - gatewayIP, err = gateway.DiscoverGateway() + gatewayIP, err := gateway.DiscoverGateway() if err != nil { return } @@ -34,7 +35,7 @@ Usage if err != nil { return } - print("External IP address:", response.ExternalIPAddress) + fmt.Println("External IP address: %v", response.ExternalIPAddress) Clients ------- diff --git a/vendor/github.com/jackpal/go-nat-pmp/natpmp.go b/vendor/github.com/jackpal/go-nat-pmp/natpmp.go index 5ca7680e41..f296c817e9 100644 --- a/vendor/github.com/jackpal/go-nat-pmp/natpmp.go +++ b/vendor/github.com/jackpal/go-nat-pmp/natpmp.go @@ -9,14 +9,14 @@ import ( // Implement the NAT-PMP protocol, typically supported by Apple routers and open source // routers such as DD-WRT and Tomato. // -// See http://tools.ietf.org/html/draft-cheshire-nat-pmp-03 +// See https://tools.ietf.org/rfc/rfc6886.txt // // Usage: // // client := natpmp.NewClient(gatewayIP) // response, err := client.GetExternalAddress() -// The recommended mapping lifetime for AddPortMapping +// The recommended mapping lifetime for AddPortMapping. const RECOMMENDED_MAPPING_LIFETIME_SECONDS = 3600 // Interface used to make remote procedure calls. @@ -49,6 +49,8 @@ type GetExternalAddressResult struct { } // Get the external address of the router. +// +// Note that this call can take up to 128 seconds to return. func (n *Client) GetExternalAddress() (result *GetExternalAddressResult, err error) { msg := make([]byte, 2) msg[0] = 0 // Version 0 @@ -71,7 +73,8 @@ type AddPortMappingResult struct { PortMappingLifetimeInSeconds uint32 } -// Add (or delete) a port mapping. To delete a mapping, set the requestedExternalPort and lifetime to 0 +// Add (or delete) a port mapping. To delete a mapping, set the requestedExternalPort and lifetime to 0. +// Note that this call can take up to 128 seconds to return. func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternalPort int, lifetime int) (result *AddPortMappingResult, err error) { var opcode byte if protocol == "udp" { @@ -85,6 +88,7 @@ func (n *Client) AddPortMapping(protocol string, internalPort, requestedExternal msg := make([]byte, 12) msg[0] = 0 // Version 0 msg[1] = opcode + // [2:3] is reserved. writeNetworkOrderUint16(msg[4:6], uint16(internalPort)) writeNetworkOrderUint16(msg[6:8], uint16(requestedExternalPort)) writeNetworkOrderUint32(msg[8:12], uint32(lifetime)) diff --git a/vendor/github.com/julienschmidt/httprouter/README.md b/vendor/github.com/julienschmidt/httprouter/README.md index 92885470b9..eabf4aad34 100644 --- a/vendor/github.com/julienschmidt/httprouter/README.md +++ b/vendor/github.com/julienschmidt/httprouter/README.md @@ -16,7 +16,7 @@ The router is optimized for high performance and a small memory footprint. It sc **Parameters in your routing pattern:** Stop parsing the requested URL path, just give the path segment a name and the router delivers the dynamic value to you. Because of the design of the router, path parameters are very cheap. -**Zero Garbage:** The matching and dispatching process generates zero bytes of garbage. In fact, the only heap allocations that are made, is by building the slice of the key-value pairs for path parameters. If the request path contains no parameters, not a single heap allocation is necessary. +**Zero Garbage:** The matching and dispatching process generates zero bytes of garbage. The only heap allocations that are made are building the slice of the key-value pairs for path parameters, and building new context and request objects (the latter only in the standard `Handler`/`HandlerFunc` api). In the 3-argument API, if the request path contains no parameters not a single heap allocation is necessary. **Best Performance:** [Benchmarks speak for themselves](https://github.com/julienschmidt/go-http-routing-benchmark). See below for technical details of the implementation. @@ -108,7 +108,7 @@ Priority Path Handle Every `*` represents the memory address of a handler function (a pointer). If you follow a path trough the tree from the root to the leaf, you get the complete route path, e.g `\blog\:post\`, where `:post` is just a placeholder ([*parameter*](#named-parameters)) for an actual post name. Unlike hash-maps, a tree structure also allows us to use dynamic parts like the `:post` parameter, since we actually match against the routing patterns instead of just comparing hashes. [As benchmarks show](https://github.com/julienschmidt/go-http-routing-benchmark), this works very well and efficient. -Since URL paths have a hierarchical structure and make use only of a limited set of characters (byte values), it is very likely that there are a lot of common prefixes. This allows us to easily reduce the routing into ever smaller problems. Moreover the router manages a separate tree for every request method. For one thing it is more space efficient than holding a method->handle map in every single node, for another thing is also allows us to greatly reduce the routing problem before even starting the look-up in the prefix-tree. +Since URL paths have a hierarchical structure and make use only of a limited set of characters (byte values), it is very likely that there are a lot of common prefixes. This allows us to easily reduce the routing into ever smaller problems. Moreover the router manages a separate tree for every request method. For one thing it is more space efficient than holding a method->handle map in every single node, it also allows us to greatly reduce the routing problem before even starting the look-up in the prefix-tree. For even better scalability, the child nodes on each tree level are ordered by priority, where the priority is just the number of handles registered in sub nodes (children, grandchildren, and so on..). This helps in two ways: @@ -149,14 +149,14 @@ Define a router per host! // We just use a map here, in which we map host names (with port) to http.Handlers type HostSwitch map[string]http.Handler -// Implement the ServerHTTP method on our new type +// Implement the ServeHTTP method on our new type func (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Check if a http.Handler is registered for the given host. // If yes, use it to handle the request. if handler := hs[r.Host]; handler != nil { handler.ServeHTTP(w, r) } else { - // Handle host names for wich no handler is registered + // Handle host names for which no handler is registered http.Error(w, "Forbidden", 403) // Or Redirect? } } diff --git a/vendor/github.com/julienschmidt/httprouter/path.go b/vendor/github.com/julienschmidt/httprouter/path.go index 486134db37..0331c7ec6d 100644 --- a/vendor/github.com/julienschmidt/httprouter/path.go +++ b/vendor/github.com/julienschmidt/httprouter/path.go @@ -41,7 +41,7 @@ func CleanPath(p string) string { buf[0] = '/' } - trailing := n > 2 && p[n-1] == '/' + trailing := n > 1 && p[n-1] == '/' // A bit more clunky without a 'lazybuf' like the path package, but the loop // gets completely inlined (bufApp). So in contrast to the path package this @@ -59,11 +59,11 @@ func CleanPath(p string) string { case p[r] == '.' && p[r+1] == '/': // . element - r++ + r += 2 case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'): // .. element: remove to last / - r += 2 + r += 3 if w > 1 { // can backtrack diff --git a/vendor/github.com/julienschmidt/httprouter/router.go b/vendor/github.com/julienschmidt/httprouter/router.go index bb1733005b..558e139226 100644 --- a/vendor/github.com/julienschmidt/httprouter/router.go +++ b/vendor/github.com/julienschmidt/httprouter/router.go @@ -236,16 +236,6 @@ func (r *Router) Handle(method, path string, handle Handle) { root.addRoute(path, handle) } -// Handler is an adapter which allows the usage of an http.Handler as a -// request handle. -func (r *Router) Handler(method, path string, handler http.Handler) { - r.Handle(method, path, - func(w http.ResponseWriter, req *http.Request, _ Params) { - handler.ServeHTTP(w, req) - }, - ) -} - // HandlerFunc is an adapter which allows the usage of an http.HandlerFunc as a // request handle. func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc) { @@ -376,13 +366,11 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { } } - if req.Method == "OPTIONS" { + if req.Method == "OPTIONS" && r.HandleOPTIONS { // Handle OPTIONS requests - if r.HandleOPTIONS { - if allow := r.allowed(path, req.Method); len(allow) > 0 { - w.Header().Set("Allow", allow) - return - } + if allow := r.allowed(path, req.Method); len(allow) > 0 { + w.Header().Set("Allow", allow) + return } } else { // Handle 405 diff --git a/vendor/vendor.json b/vendor/vendor.json index bbf0a01156..eb27ec420a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -3,10 +3,10 @@ "ignore": "test", "package": [ { - "checksumSHA1": "z+M6FYl9EKsoZZMLcT0Ktwfk8pI=", + "checksumSHA1": "xrIesz0blvPSWEz5hsS85bcM04o=", "path": "github.com/Azure/azure-pipeline-go/pipeline", - "revision": "7571e8eb0876932ab505918ff7ed5107773e5ee2", - "revisionTime": "2018-06-07T21:19:23Z" + "revision": "55fedc85a614dcd0e942a66f302ae3efb83d563c", + "revisionTime": "2019-04-17T01:50:18Z" }, { "checksumSHA1": "5nsGu77r69lloEWbFhMof2UA9rY=", @@ -15,22 +15,22 @@ "revisionTime": "2018-07-12T00:56:34Z" }, { - "checksumSHA1": "QC55lHNOv1+UAL2xtIHw17MJ8J8=", + "checksumSHA1": "+uOjgDmeVWUwUI9l/AVZGa6+yQs=", "path": "github.com/StackExchange/wmi", - "revision": "5d049714c4a64225c3c79a7cf7d02f7fb5b96338", - "revisionTime": "2018-01-16T20:38:02Z" + "revision": "cbe66965904dbe8a6cd589e2298e5d8b986bd7dd", + "revisionTime": "2019-05-23T21:33:15Z" }, { - "checksumSHA1": "8skJYOdQytXjimcDPLRW4tonX3A=", + "checksumSHA1": "q2qmF0r4PmyMnsDb/CUj8GJET9Q=", "path": "github.com/allegro/bigcache", - "revision": "e24eb225f15679bbe54f91bfa7da3b00e59b9768", - "revisionTime": "2019-02-18T06:46:05Z" + "revision": "69ea0af04088faa57adb9ac683934277141e92a5", + "revisionTime": "2019-06-18T19:10:10Z" }, { "checksumSHA1": "vtT7NcYLatJmxVQQEeSESyrgVg0=", "path": "github.com/allegro/bigcache/queue", - "revision": "e24eb225f15679bbe54f91bfa7da3b00e59b9768", - "revisionTime": "2019-02-18T06:46:05Z" + "revision": "69ea0af04088faa57adb9ac683934277141e92a5", + "revisionTime": "2019-06-18T19:10:10Z" }, { "checksumSHA1": "hp2pna9yEn9hemIjc7asalxL2Qs=", @@ -39,76 +39,76 @@ "revisionTime": "2018-07-02T11:14:01Z" }, { - "checksumSHA1": "USkefO0g1U9mr+8hagv3fpSkrxg=", + "checksumSHA1": "kto0asmOE+Nuhj7T8cvrvIwq2ak=", "path": "github.com/aristanetworks/goarista/monotime", - "revision": "ea17b1a17847fb6e4c0a91de0b674704693469b0", - "revisionTime": "2017-02-10T01:56:32Z" + "revision": "52c2a7864a0891eefaed13a457510c7405a7105b", + "revisionTime": "2019-06-07T11:12:40Z" }, { - "checksumSHA1": "gZQ6HheWahvZzIc3phBnOwoWHjE=", + "checksumSHA1": "WBJp3KWXMrlROP4qZWhZq0dvnLM=", "path": "github.com/btcsuite/btcd/btcec", - "revision": "2e60448ffcc6bf78332d1fe590260095f554dd78", - "revisionTime": "2017-11-28T15:02:46Z" + "revision": "962a206e94e9151fe41bbd6d6464af4ba7168f50", + "revisionTime": "2019-06-14T01:37:41Z" }, { - "checksumSHA1": "cDMtzKmdTx4CcIpP4broa+16X9g=", + "checksumSHA1": "Q43R3tBW9/xOqcSTQ2dm7+2I2LY=", "path": "github.com/cespare/cp", - "revision": "165db2f241fd235aec29ba6d9b1ccd5f1c14637c", - "revisionTime": "2015-01-22T07:26:53Z" + "revision": "db1407d84ae423533fe1d25510c1c4c4d831f0fc", + "revisionTime": "2018-12-20T00:00:49Z" }, { - "checksumSHA1": "dvabztWVQX8f6oMLRyv4dLH+TGY=", + "checksumSHA1": "CSPbwbyzqA6sfORicn4HFtIhF/c=", "path": "github.com/davecgh/go-spew/spew", - "revision": "346938d642f2ec3594ed81d874461961cd0faa76", - "revisionTime": "2016-10-29T20:57:26Z" + "revision": "d8f796af33cc11cb798c1aaeb27a4ebc5099927d", + "revisionTime": "2018-08-30T19:11:22Z" }, { - "checksumSHA1": "1xK7ycc1ICRInk/S9iiyB9Rpv50=", + "checksumSHA1": "vwNjR8772Pqs8z9ZdPFoatNI9Kg=", "path": "github.com/deckarep/golang-set", - "revision": "504e848d77ea4752b3057b8fb46da0e7f746ccf3", - "revisionTime": "2018-06-03T19:32:48Z" + "revision": "699df6a3acf6867538e50931511e9dc403da108a", + "revisionTime": "2018-09-27T02:58:44Z" }, { "checksumSHA1": "Ad8LPSCP9HctFrmskh+S5HpHXcs=", "path": "github.com/docker/docker/pkg/reexec", - "revision": "8e610b2b55bfd1bfa9436ab110d311f5e8a74dcb", - "revisionTime": "2018-06-25T18:44:42Z" + "revision": "52c16677b22d0aafc0e56db04e691164d46bb2c4", + "revisionTime": "2019-06-21T08:12:58Z" }, { - "checksumSHA1": "zYnPsNAVm1/ViwCkN++dX2JQhBo=", + "checksumSHA1": "Vdaftt1J1nSEmhiLz4m90YY+S0A=", "path": "github.com/edsrzf/mmap-go", - "revision": "935e0e8a636ca4ba70b713f3e38a19e1b77739e8", - "revisionTime": "2016-05-12T03:30:02Z" + "revision": "904c4ced31cdffe19e971afa0b3d319ff06d9c72", + "revisionTime": "2018-12-22T14:20:22Z" }, { - "checksumSHA1": "jElNoLEe7m/iaoF1vYIHyNaS2SE=", + "checksumSHA1": "tuhGcluN3UtoiFBovqsep6aPx3s=", "path": "github.com/elastic/gosigar", - "revision": "37f05ff46ffa7a825d1b24cf2b62d4a4c1a9d2e8", - "revisionTime": "2018-03-30T10:04:40Z" + "revision": "99ed9cf55303a9d3936cb656b9a86a4a6e67b30a", + "revisionTime": "2019-05-27T11:32:19Z" }, { - "checksumSHA1": "qDsgp2kAeI9nhj565HUScaUyjU4=", + "checksumSHA1": "R70u1XUHH/t1pquvHEFDeUFtkFk=", "path": "github.com/elastic/gosigar/sys/windows", - "revision": "a3814ce5008e612a0c6d027608b54e1d0d9a5613", - "revisionTime": "2018-01-22T22:25:45Z" + "revision": "99ed9cf55303a9d3936cb656b9a86a4a6e67b30a", + "revisionTime": "2019-05-27T11:32:19Z" }, { - "checksumSHA1": "7oFpbmDfGobwKsFLIf6wMUvVoKw=", + "checksumSHA1": "BxH9xJUqczhpL57gfKZe2/VlBHY=", "path": "github.com/fatih/color", - "revision": "5ec5d9d3c2cf82e9688b34e9bc27a94d616a7193", - "revisionTime": "2017-02-09T08:00:14Z" + "revision": "3f9d52f7176a6927daacff70a3e8d1dc2025c53e", + "revisionTime": "2018-10-10T23:13:11Z" }, { - "checksumSHA1": "Jq1rrHSGPfh689nA2hL1QVb62zE=", + "checksumSHA1": "IfDucP2AWAj+1uW+ho6NEEDG7nk=", "path": "github.com/fjl/memsize", - "revision": "ca190fb6ffbc076ff49197b7168a760f30182d2e", - "revisionTime": "2018-04-18T12:24:29Z" + "revision": "2a09253e352a56f419bd88effab0483f52da4c7d", + "revisionTime": "2018-09-29T19:40:37Z" }, { "checksumSHA1": "Z13QAYTqeW4cTiglkc2F05gWLu4=", "path": "github.com/fjl/memsize/memsizeui", - "revision": "ca190fb6ffbc076ff49197b7168a760f30182d2e", - "revisionTime": "2018-04-18T12:24:29Z" + "revision": "2a09253e352a56f419bd88effab0483f52da4c7d", + "revisionTime": "2018-09-29T19:40:37Z" }, { "checksumSHA1": "gsiYVjwKzFKe+JuIimgKlrPyipA=", @@ -117,22 +117,22 @@ "revisionTime": "2019-06-07T06:51:34Z" }, { - "checksumSHA1": "gxV/cPPLkByTdY8y172t7v4qcZA=", + "checksumSHA1": "vTmc/uvCPpTs51Rl9bVomPZMZIM=", "path": "github.com/go-ole/go-ole", - "revision": "a41e3c4b706f6ae8dfbff342b06e40fa4d2d0506", - "revisionTime": "2017-11-10T16:07:06Z" + "revision": "97b6244175ae18ea6eef668034fd6565847501c9", + "revisionTime": "2019-02-26T14:26:00Z" }, { "checksumSHA1": "PArleDBtadu2qO4hJwHR8a3IOTA=", "path": "github.com/go-ole/go-ole/oleutil", - "revision": "a41e3c4b706f6ae8dfbff342b06e40fa4d2d0506", - "revisionTime": "2017-11-10T16:07:06Z" + "revision": "97b6244175ae18ea6eef668034fd6565847501c9", + "revisionTime": "2019-02-26T14:26:00Z" }, { - "checksumSHA1": "KZ3QD2QgUS4RcoKiA3mn5pSlJxQ=", + "checksumSHA1": "H8wo+NR5z+VRl0wqPYpVQfC06ks=", "path": "github.com/go-stack/stack", - "revision": "54be5f394ed2c3e19dac9134a40a95ba5a017f7b", - "revisionTime": "2017-07-10T16:04:46Z" + "revision": "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a", + "revisionTime": "2018-08-26T13:48:48Z" }, { "checksumSHA1": "CGj8VcI/CpzxaNqlqpEVM7qElD4=", @@ -147,22 +147,106 @@ "revisionTime": "2019-05-17T06:12:10Z" }, { - "checksumSHA1": "p/8vSviYF91gFflhrt5vkyksroo=", + "checksumSHA1": "L3HoHVqp2EaBSOqBxB7l0PTyu7g=", "path": "github.com/golang/snappy", - "revision": "553a641470496b2327abcac10b36396bd98e45c9", - "revisionTime": "2017-02-15T23:32:05Z" + "revision": "2a8bb927dd31d8daada140a5d09578521ce5c36a", + "revisionTime": "2019-02-18T23:22:22Z" }, { - "checksumSHA1": "d9PxF1XQGLMJZRct2R8qVM/eYlE=", + "checksumSHA1": "2Ow9mKLW+Bs7kKc2VAurAt65ke4=", + "path": "github.com/graph-gophers/graphql-go", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "nSpiywJOLU4e01NPAQf4lBtnKtw=", + "path": "github.com/graph-gophers/graphql-go/errors", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "vKQxqeKlmMEYjgHISd1nmdVASGs=", + "path": "github.com/graph-gophers/graphql-go/internal/common", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "4dn67lmOWtvQNr7YF/KDux+oYLU=", + "path": "github.com/graph-gophers/graphql-go/internal/exec", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "Bucl75VZRgPBboreGJQKIv/RHcY=", + "path": "github.com/graph-gophers/graphql-go/internal/exec/packer", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "YBLNBJzcLnMDqgJRV0MY52TVOyE=", + "path": "github.com/graph-gophers/graphql-go/internal/exec/resolvable", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "AG9OwCZI6uncNdsLnYzetvGhgoM=", + "path": "github.com/graph-gophers/graphql-go/internal/exec/selected", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "VSDhUJOJzbyTIeYfunqWTTKDBok=", + "path": "github.com/graph-gophers/graphql-go/internal/query", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "jWj+ES9xBD5AAiOv1kqRVm+C/kM=", + "path": "github.com/graph-gophers/graphql-go/internal/schema", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "MhEoghTb3LXzuOwS19qKgZtrZOM=", + "path": "github.com/graph-gophers/graphql-go/internal/validation", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "JY1146PnFG5ZY82Drfti2yW6Wqo=", + "path": "github.com/graph-gophers/graphql-go/introspection", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "Bv2f9HtxVix0i3vgwGUMfIeBVRQ=", + "path": "github.com/graph-gophers/graphql-go/log", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "h9lR2l7dWiXo/yF4zq6XZE4MEBY=", + "path": "github.com/graph-gophers/graphql-go/relay", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "4rdWXZp7lvNmRwUHYnELTPng8/8=", + "path": "github.com/graph-gophers/graphql-go/trace", + "revision": "8f92f34fc59823d34fc08bfdc9fd266b854e2b50", + "revisionTime": "2019-06-10T16:17:39Z" + }, + { + "checksumSHA1": "/04S+1K8V7ix4YQ9TdYUA+MMdRo=", "path": "github.com/hashicorp/golang-lru", - "revision": "0a025b7e63adc15a622f29b0b2c4c3848243bbf6", - "revisionTime": "2016-08-13T22:13:03Z" + "revision": "59383c442f7d7b190497e9bb8fc17a48d06cd03f", + "revisionTime": "2019-05-20T14:04:33Z" }, { - "checksumSHA1": "9hffs0bAIU6CquiRhKQdzjHnKt0=", + "checksumSHA1": "oPFbkG2QReaXuViYt+zMXLdT4Mo=", "path": "github.com/hashicorp/golang-lru/simplelru", - "revision": "0a025b7e63adc15a622f29b0b2c4c3848243bbf6", - "revisionTime": "2016-08-13T22:13:03Z" + "revision": "59383c442f7d7b190497e9bb8fc17a48d06cd03f", + "revisionTime": "2019-05-20T14:04:33Z" }, { "checksumSHA1": "ZxzYc1JwJ3U6kZbw/KGuPko5lSY=", @@ -171,46 +255,46 @@ "revisionTime": "2015-10-03T19:46:02Z" }, { - "checksumSHA1": "f55gR+6YClh0i/FOhdy66SOUiwY=", + "checksumSHA1": "RBg+tt0WVRJPktk4/0hjW/oMHgo=", "path": "github.com/huin/goupnp", - "revision": "679507af18f3c7ba2bcc7905392ce23e148661c3", - "revisionTime": "2016-12-24T10:41:01Z" + "revision": "656e61dfadd241c7cbdd22a023fa81ecb6860ea8", + "revisionTime": "2018-10-13T14:04:17Z" }, { - "checksumSHA1": "U3NsxkodNX/tmOqkVDnGFRZ6dI4=", + "checksumSHA1": "xpDViB1cPwd5TRhi8M1lsi+tLeQ=", "path": "github.com/huin/goupnp/dcps/internetgateway1", - "revision": "679507af18f3c7ba2bcc7905392ce23e148661c3", - "revisionTime": "2016-12-24T10:41:01Z" + "revision": "656e61dfadd241c7cbdd22a023fa81ecb6860ea8", + "revisionTime": "2018-10-13T14:04:17Z" }, { - "checksumSHA1": "znTn+P/iEwi6Ax7r3N0GikeYMlk=", + "checksumSHA1": "IgbsyspRShLpG4bJXr9+jIOBuzA=", "path": "github.com/huin/goupnp/dcps/internetgateway2", - "revision": "679507af18f3c7ba2bcc7905392ce23e148661c3", - "revisionTime": "2016-12-24T10:41:01Z" + "revision": "656e61dfadd241c7cbdd22a023fa81ecb6860ea8", + "revisionTime": "2018-10-13T14:04:17Z" }, { - "checksumSHA1": "RLygtUlTOCtrI3KMswYLJnte1OU=", + "checksumSHA1": "CSFM1dzHvJr3u7cvSw2hr58+/5E=", "path": "github.com/huin/goupnp/httpu", - "revision": "679507af18f3c7ba2bcc7905392ce23e148661c3", - "revisionTime": "2016-12-24T10:41:01Z" + "revision": "656e61dfadd241c7cbdd22a023fa81ecb6860ea8", + "revisionTime": "2018-10-13T14:04:17Z" }, { "checksumSHA1": "+S2t2qKK+wcpM+07eW7dCK/6oFU=", "path": "github.com/huin/goupnp/scpd", - "revision": "679507af18f3c7ba2bcc7905392ce23e148661c3", - "revisionTime": "2016-12-24T10:41:01Z" + "revision": "656e61dfadd241c7cbdd22a023fa81ecb6860ea8", + "revisionTime": "2018-10-13T14:04:17Z" }, { - "checksumSHA1": "80ieA8iPFaFeQFw++EiYn4jhcGs=", + "checksumSHA1": "GW81GsQSWYvxK6XoRJ6L+Op5bKg=", "path": "github.com/huin/goupnp/soap", - "revision": "679507af18f3c7ba2bcc7905392ce23e148661c3", - "revisionTime": "2016-12-24T10:41:01Z" + "revision": "656e61dfadd241c7cbdd22a023fa81ecb6860ea8", + "revisionTime": "2018-10-13T14:04:17Z" }, { - "checksumSHA1": "iqPUC/MoFGaRQnAudYGAW9BvF2o=", + "checksumSHA1": "PDmT/Xpscyf2Qc6XWYQ/yy8zz7w=", "path": "github.com/huin/goupnp/ssdp", - "revision": "679507af18f3c7ba2bcc7905392ce23e148661c3", - "revisionTime": "2016-12-24T10:41:01Z" + "revision": "656e61dfadd241c7cbdd22a023fa81ecb6860ea8", + "revisionTime": "2018-10-13T14:04:17Z" }, { "checksumSHA1": "6tNwbL5tUS0dxYzADKVZtI2d/lE=", @@ -219,28 +303,28 @@ "revisionTime": "2017-10-09T17:24:46Z" }, { - "checksumSHA1": "cfumoC9gHEUROd+fA8qK3WLFAZQ=", + "checksumSHA1": "Z2XCUBzGGV6d2jP6vzOvG01v6LA=", "path": "github.com/influxdata/influxdb/models", - "revision": "b36b9f109f2da91c8941679caf5356e08eee0b2b", - "revisionTime": "2018-01-17T01:42:09Z" + "revision": "d45786570411039c77918315b96f9d6aecce53ec", + "revisionTime": "2019-06-21T23:19:42Z" }, { "checksumSHA1": "Z0Bb5PWa5WL/j5Dm2KJCLGn1l7U=", "path": "github.com/influxdata/influxdb/pkg/escape", - "revision": "01288bdb0883a01cac999326bd34421b29acaec8", - "revisionTime": "2018-02-21T22:33:40Z" + "revision": "d45786570411039c77918315b96f9d6aecce53ec", + "revisionTime": "2019-06-21T23:19:42Z" }, { - "checksumSHA1": "vTGKMIfiMwz43y5bsgx9PrL+AVw=", + "checksumSHA1": "RB2di6332iVfJoNbxC9lr6t3ScE=", "path": "github.com/jackpal/go-nat-pmp", - "revision": "1fa385a6f45828c83361136b45b1a21a12139493", - "revisionTime": "2016-06-03T03:41:37Z" + "revision": "d89d09f6f3329bc3c2479aa3cafd76a5aa93a35c", + "revisionTime": "2018-10-21T19:25:11Z" }, { - "checksumSHA1": "gKyBj05YkfuLFruAyPZ4KV9nFp8=", + "checksumSHA1": "z/DzcKNumSHzzxg9Widbi9KgwNw=", "path": "github.com/julienschmidt/httprouter", - "revision": "975b5c4c7c21c0e3d2764200bf2aa8e34657ae6e", - "revisionTime": "2017-04-30T22:20:11Z" + "revision": "26a05976f9bf5c3aa992cc20e8588c359418ee58", + "revisionTime": "2018-10-21T22:38:31Z" }, { "checksumSHA1": "TU/WaqL7fYPDovmGVRSo8btD4ZM=", @@ -274,6 +358,10 @@ "revision": "c48cc78d482608239f6c4c92a4abd87eb8761c90", "revisionTime": "2017-09-29T03:49:55Z" }, + { + "path": "github.com/naoina/go-stringutil", + "revision": "" + }, { "checksumSHA1": "FYM/8R2CqS6PSNAoKl6X5gNJ20A=", "path": "github.com/naoina/toml",