1.修改代码适配阿里云的服务器
This commit is contained in:
60
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/awserr/error.go
generated
vendored
Normal file
60
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/awserr/error.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Based on github.com/aws/aws-sdk-go by Amazon.com, Inc. with code from:
|
||||
// - github.com/aws/aws-sdk-go/blob/v1.44.225/aws/awserr/error.go
|
||||
// See THIRD-PARTY-NOTICES for original license terms
|
||||
|
||||
// Package awserr represents API error interface accessors for the SDK.
|
||||
package awserr
|
||||
|
||||
// An Error wraps lower level errors with code, message and an original error.
|
||||
// The underlying concrete error type may also satisfy other interfaces which
|
||||
// can be to used to obtain more specific information about the error.
|
||||
type Error interface {
|
||||
// Satisfy the generic error interface.
|
||||
error
|
||||
|
||||
// Returns the short phrase depicting the classification of the error.
|
||||
Code() string
|
||||
|
||||
// Returns the error details message.
|
||||
Message() string
|
||||
|
||||
// Returns the original error if one was set. Nil is returned if not set.
|
||||
OrigErr() error
|
||||
}
|
||||
|
||||
// BatchedErrors is a batch of errors which also wraps lower level errors with
|
||||
// code, message, and original errors. Calling Error() will include all errors
|
||||
// that occurred in the batch.
|
||||
//
|
||||
// Replaces BatchError
|
||||
type BatchedErrors interface {
|
||||
// Satisfy the base Error interface.
|
||||
Error
|
||||
|
||||
// Returns the original error if one was set. Nil is returned if not set.
|
||||
OrigErrs() []error
|
||||
}
|
||||
|
||||
// New returns an Error object described by the code, message, and origErr.
|
||||
//
|
||||
// If origErr satisfies the Error interface it will not be wrapped within a new
|
||||
// Error object and will instead be returned.
|
||||
func New(code, message string, origErr error) Error {
|
||||
var errs []error
|
||||
if origErr != nil {
|
||||
errs = append(errs, origErr)
|
||||
}
|
||||
return newBaseError(code, message, errs)
|
||||
}
|
||||
|
||||
// NewBatchError returns an BatchedErrors with a collection of errors as an
|
||||
// array of errors.
|
||||
func NewBatchError(code, message string, errs []error) BatchedErrors {
|
||||
return newBaseError(code, message, errs)
|
||||
}
|
||||
144
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/awserr/types.go
generated
vendored
Normal file
144
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/awserr/types.go
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Based on github.com/aws/aws-sdk-go by Amazon.com, Inc. with code from:
|
||||
// - github.com/aws/aws-sdk-go/blob/v1.44.225/aws/awserr/types.go
|
||||
// See THIRD-PARTY-NOTICES for original license terms
|
||||
|
||||
package awserr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// SprintError returns a string of the formatted error code.
|
||||
//
|
||||
// Both extra and origErr are optional. If they are included their lines
|
||||
// will be added, but if they are not included their lines will be ignored.
|
||||
func SprintError(code, message, extra string, origErr error) string {
|
||||
msg := fmt.Sprintf("%s: %s", code, message)
|
||||
if extra != "" {
|
||||
msg = fmt.Sprintf("%s\n\t%s", msg, extra)
|
||||
}
|
||||
if origErr != nil {
|
||||
msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error())
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
// A baseError wraps the code and message which defines an error. It also
|
||||
// can be used to wrap an original error object.
|
||||
//
|
||||
// Should be used as the root for errors satisfying the awserr.Error. Also
|
||||
// for any error which does not fit into a specific error wrapper type.
|
||||
type baseError struct {
|
||||
// Classification of error
|
||||
code string
|
||||
|
||||
// Detailed information about error
|
||||
message string
|
||||
|
||||
// Optional original error this error is based off of. Allows building
|
||||
// chained errors.
|
||||
errs []error
|
||||
}
|
||||
|
||||
// newBaseError returns an error object for the code, message, and errors.
|
||||
//
|
||||
// code is a short no whitespace phrase depicting the classification of
|
||||
// the error that is being created.
|
||||
//
|
||||
// message is the free flow string containing detailed information about the
|
||||
// error.
|
||||
//
|
||||
// origErrs is the error objects which will be nested under the new errors to
|
||||
// be returned.
|
||||
func newBaseError(code, message string, origErrs []error) *baseError {
|
||||
b := &baseError{
|
||||
code: code,
|
||||
message: message,
|
||||
errs: origErrs,
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// Error returns the string representation of the error.
|
||||
//
|
||||
// See ErrorWithExtra for formatting.
|
||||
//
|
||||
// Satisfies the error interface.
|
||||
func (b baseError) Error() string {
|
||||
size := len(b.errs)
|
||||
if size > 0 {
|
||||
return SprintError(b.code, b.message, "", errorList(b.errs))
|
||||
}
|
||||
|
||||
return SprintError(b.code, b.message, "", nil)
|
||||
}
|
||||
|
||||
// String returns the string representation of the error.
|
||||
// Alias for Error to satisfy the stringer interface.
|
||||
func (b baseError) String() string {
|
||||
return b.Error()
|
||||
}
|
||||
|
||||
// Code returns the short phrase depicting the classification of the error.
|
||||
func (b baseError) Code() string {
|
||||
return b.code
|
||||
}
|
||||
|
||||
// Message returns the error details message.
|
||||
func (b baseError) Message() string {
|
||||
return b.message
|
||||
}
|
||||
|
||||
// OrigErr returns the original error if one was set. Nil is returned if no
|
||||
// error was set. This only returns the first element in the list. If the full
|
||||
// list is needed, use BatchedErrors.
|
||||
func (b baseError) OrigErr() error {
|
||||
switch len(b.errs) {
|
||||
case 0:
|
||||
return nil
|
||||
case 1:
|
||||
return b.errs[0]
|
||||
default:
|
||||
if err, ok := b.errs[0].(Error); ok {
|
||||
return NewBatchError(err.Code(), err.Message(), b.errs[1:])
|
||||
}
|
||||
return NewBatchError("BatchedErrors",
|
||||
"multiple errors occurred", b.errs)
|
||||
}
|
||||
}
|
||||
|
||||
// OrigErrs returns the original errors if one was set. An empty slice is
|
||||
// returned if no error was set.
|
||||
func (b baseError) OrigErrs() []error {
|
||||
return b.errs
|
||||
}
|
||||
|
||||
// An error list that satisfies the golang interface
|
||||
type errorList []error
|
||||
|
||||
// Error returns the string representation of the error.
|
||||
//
|
||||
// Satisfies the error interface.
|
||||
func (e errorList) Error() string {
|
||||
msg := ""
|
||||
// How do we want to handle the array size being zero
|
||||
if size := len(e); size > 0 {
|
||||
for i := 0; i < size; i++ {
|
||||
msg += e[i].Error()
|
||||
// We check the next index to see if it is within the slice.
|
||||
// If it is, then we append a newline. We do this, because unit tests
|
||||
// could be broken with the additional '\n'
|
||||
if i+1 < size {
|
||||
msg += "\n"
|
||||
}
|
||||
}
|
||||
}
|
||||
return msg
|
||||
}
|
||||
72
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/chain_provider.go
generated
vendored
Normal file
72
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/chain_provider.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Based on github.com/aws/aws-sdk-go by Amazon.com, Inc. with code from:
|
||||
// - github.com/aws/aws-sdk-go/blob/v1.44.225/aws/credentials/chain_provider.go
|
||||
// See THIRD-PARTY-NOTICES for original license terms
|
||||
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/v2/internal/aws/awserr"
|
||||
)
|
||||
|
||||
// A ChainProvider will search for a provider which returns credentials
|
||||
// and cache that provider until Retrieve is called again.
|
||||
//
|
||||
// The ChainProvider provides a way of chaining multiple providers together
|
||||
// which will pick the first available using priority order of the Providers
|
||||
// in the list.
|
||||
//
|
||||
// If none of the Providers retrieve valid credentials Value, ChainProvider's
|
||||
// Retrieve() will return the error ErrNoValidProvidersFoundInChain.
|
||||
//
|
||||
// If a Provider is found which returns valid credentials Value ChainProvider
|
||||
// will cache that Provider for all calls to IsExpired(), until Retrieve is
|
||||
// called again.
|
||||
type ChainProvider struct {
|
||||
Providers []Provider
|
||||
curr Provider
|
||||
}
|
||||
|
||||
// NewChainCredentials returns a pointer to a new Credentials object
|
||||
// wrapping a chain of providers.
|
||||
func NewChainCredentials(providers []Provider) *Credentials {
|
||||
return NewCredentials(&ChainProvider{
|
||||
Providers: append([]Provider{}, providers...),
|
||||
})
|
||||
}
|
||||
|
||||
// Retrieve returns the credentials value or error if no provider returned
|
||||
// without error.
|
||||
//
|
||||
// If a provider is found it will be cached and any calls to IsExpired()
|
||||
// will return the expired state of the cached provider.
|
||||
func (c *ChainProvider) Retrieve() (Value, error) {
|
||||
errs := make([]error, 0, len(c.Providers))
|
||||
for _, p := range c.Providers {
|
||||
creds, err := p.Retrieve()
|
||||
if err == nil {
|
||||
c.curr = p
|
||||
return creds, nil
|
||||
}
|
||||
errs = append(errs, err)
|
||||
}
|
||||
c.curr = nil
|
||||
|
||||
err := awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs)
|
||||
return Value{}, err
|
||||
}
|
||||
|
||||
// IsExpired will returned the expired state of the currently cached provider
|
||||
// if there is one. If there is no current provider, true will be returned.
|
||||
func (c *ChainProvider) IsExpired() bool {
|
||||
if c.curr != nil {
|
||||
return c.curr.IsExpired()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
197
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/credentials.go
generated
vendored
Normal file
197
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/credentials/credentials.go
generated
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Based on github.com/aws/aws-sdk-go by Amazon.com, Inc. with code from:
|
||||
// - github.com/aws/aws-sdk-go/blob/v1.44.225/aws/credentials/credentials.go
|
||||
// See THIRD-PARTY-NOTICES for original license terms
|
||||
|
||||
package credentials
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/internal/aws/awserr"
|
||||
"golang.org/x/sync/singleflight"
|
||||
)
|
||||
|
||||
// A Value is the AWS credentials value for individual credential fields.
|
||||
//
|
||||
// A Value is also used to represent Azure credentials.
|
||||
// Azure credentials only consist of an access token, which is stored in the `SessionToken` field.
|
||||
type Value struct {
|
||||
// AWS Access key ID
|
||||
AccessKeyID string
|
||||
|
||||
// AWS Secret Access Key
|
||||
SecretAccessKey string
|
||||
|
||||
// AWS Session Token
|
||||
SessionToken string
|
||||
|
||||
// Provider used to get credentials
|
||||
ProviderName string
|
||||
}
|
||||
|
||||
// HasKeys returns if the credentials Value has both AccessKeyID and
|
||||
// SecretAccessKey value set.
|
||||
func (v Value) HasKeys() bool {
|
||||
return len(v.AccessKeyID) != 0 && len(v.SecretAccessKey) != 0
|
||||
}
|
||||
|
||||
// A Provider is the interface for any component which will provide credentials
|
||||
// Value. A provider is required to manage its own Expired state, and what to
|
||||
// be expired means.
|
||||
//
|
||||
// The Provider should not need to implement its own mutexes, because
|
||||
// that will be managed by Credentials.
|
||||
type Provider interface {
|
||||
// Retrieve returns nil if it successfully retrieved the value.
|
||||
// Error is returned if the value were not obtainable, or empty.
|
||||
Retrieve() (Value, error)
|
||||
|
||||
// IsExpired returns if the credentials are no longer valid, and need
|
||||
// to be retrieved.
|
||||
IsExpired() bool
|
||||
}
|
||||
|
||||
// ProviderWithContext is a Provider that can retrieve credentials with a Context
|
||||
type ProviderWithContext interface {
|
||||
Provider
|
||||
|
||||
RetrieveWithContext(context.Context) (Value, error)
|
||||
}
|
||||
|
||||
// A Credentials provides concurrency safe retrieval of AWS credentials Value.
|
||||
//
|
||||
// A Credentials is also used to fetch Azure credentials Value.
|
||||
//
|
||||
// Credentials will cache the credentials value until they expire. Once the value
|
||||
// expires the next Get will attempt to retrieve valid credentials.
|
||||
//
|
||||
// Credentials is safe to use across multiple goroutines and will manage the
|
||||
// synchronous state so the Providers do not need to implement their own
|
||||
// synchronization.
|
||||
//
|
||||
// The first Credentials.Get() will always call Provider.Retrieve() to get the
|
||||
// first instance of the credentials Value. All calls to Get() after that
|
||||
// will return the cached credentials Value until IsExpired() returns true.
|
||||
type Credentials struct {
|
||||
sf singleflight.Group
|
||||
|
||||
m sync.RWMutex
|
||||
creds Value
|
||||
provider Provider
|
||||
}
|
||||
|
||||
// NewCredentials returns a pointer to a new Credentials with the provider set.
|
||||
func NewCredentials(provider Provider) *Credentials {
|
||||
c := &Credentials{
|
||||
provider: provider,
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// GetWithContext returns the credentials value, or error if the credentials
|
||||
// Value failed to be retrieved. Will return early if the passed in context is
|
||||
// canceled.
|
||||
//
|
||||
// Will return the cached credentials Value if it has not expired. If the
|
||||
// credentials Value has expired the Provider's Retrieve() will be called
|
||||
// to refresh the credentials.
|
||||
//
|
||||
// If Credentials.Expire() was called the credentials Value will be force
|
||||
// expired, and the next call to Get() will cause them to be refreshed.
|
||||
func (c *Credentials) GetWithContext(ctx context.Context) (Value, error) {
|
||||
// Check if credentials are cached, and not expired.
|
||||
select {
|
||||
case curCreds, ok := <-c.asyncIsExpired():
|
||||
// ok will only be true, of the credentials were not expired. ok will
|
||||
// be false and have no value if the credentials are expired.
|
||||
if ok {
|
||||
return curCreds, nil
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return Value{}, awserr.New("RequestCanceled",
|
||||
"request context canceled", ctx.Err())
|
||||
}
|
||||
|
||||
// Cannot pass context down to the actual retrieve, because the first
|
||||
// context would cancel the whole group when there is not direct
|
||||
// association of items in the group.
|
||||
resCh := c.sf.DoChan("", func() (interface{}, error) {
|
||||
return c.singleRetrieve(&suppressedContext{ctx})
|
||||
})
|
||||
select {
|
||||
case res := <-resCh:
|
||||
return res.Val.(Value), res.Err
|
||||
case <-ctx.Done():
|
||||
return Value{}, awserr.New("RequestCanceled",
|
||||
"request context canceled", ctx.Err())
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Credentials) singleRetrieve(ctx context.Context) (interface{}, error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
if curCreds := c.creds; !c.isExpiredLocked(curCreds) {
|
||||
return curCreds, nil
|
||||
}
|
||||
|
||||
var creds Value
|
||||
var err error
|
||||
if p, ok := c.provider.(ProviderWithContext); ok {
|
||||
creds, err = p.RetrieveWithContext(ctx)
|
||||
} else {
|
||||
creds, err = c.provider.Retrieve()
|
||||
}
|
||||
if err == nil {
|
||||
c.creds = creds
|
||||
}
|
||||
|
||||
return creds, err
|
||||
}
|
||||
|
||||
// asyncIsExpired returns a channel of credentials Value. If the channel is
|
||||
// closed the credentials are expired and credentials value are not empty.
|
||||
func (c *Credentials) asyncIsExpired() <-chan Value {
|
||||
ch := make(chan Value, 1)
|
||||
go func() {
|
||||
c.m.RLock()
|
||||
defer c.m.RUnlock()
|
||||
|
||||
if curCreds := c.creds; !c.isExpiredLocked(curCreds) {
|
||||
ch <- curCreds
|
||||
}
|
||||
|
||||
close(ch)
|
||||
}()
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
// isExpiredLocked helper method wrapping the definition of expired credentials.
|
||||
func (c *Credentials) isExpiredLocked(creds interface{}) bool {
|
||||
return creds == nil || creds.(Value) == Value{} || c.provider.IsExpired()
|
||||
}
|
||||
|
||||
type suppressedContext struct {
|
||||
context.Context
|
||||
}
|
||||
|
||||
func (s *suppressedContext) Deadline() (deadline time.Time, ok bool) {
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
func (s *suppressedContext) Done() <-chan struct{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *suppressedContext) Err() error {
|
||||
return nil
|
||||
}
|
||||
51
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/header_rules.go
generated
vendored
Normal file
51
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/header_rules.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Based on github.com/aws/aws-sdk-go by Amazon.com, Inc. with code from:
|
||||
// - github.com/aws/aws-sdk-go/blob/v1.44.225/aws/signer/v4/header_rules.go
|
||||
// See THIRD-PARTY-NOTICES for original license terms
|
||||
|
||||
package v4
|
||||
|
||||
// validator houses a set of rule needed for validation of a
|
||||
// string value
|
||||
type rules []rule
|
||||
|
||||
// rule interface allows for more flexible rules and just simply
|
||||
// checks whether or not a value adheres to that rule
|
||||
type rule interface {
|
||||
IsValid(value string) bool
|
||||
}
|
||||
|
||||
// IsValid will iterate through all rules and see if any rules
|
||||
// apply to the value and supports nested rules
|
||||
func (r rules) IsValid(value string) bool {
|
||||
for _, rule := range r {
|
||||
if rule.IsValid(value) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// mapRule generic rule for maps
|
||||
type mapRule map[string]struct{}
|
||||
|
||||
// IsValid for the map rule satisfies whether it exists in the map
|
||||
func (m mapRule) IsValid(value string) bool {
|
||||
_, ok := m[value]
|
||||
return ok
|
||||
}
|
||||
|
||||
// excludeList is a generic rule for exclude listing
|
||||
type excludeList struct {
|
||||
rule
|
||||
}
|
||||
|
||||
// IsValid for exclude list checks if the value is within the exclude list
|
||||
func (b excludeList) IsValid(value string) bool {
|
||||
return !b.rule.IsValid(value)
|
||||
}
|
||||
80
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/request.go
generated
vendored
Normal file
80
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/request.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Based on github.com/aws/aws-sdk-go by Amazon.com, Inc. with code from:
|
||||
// - github.com/aws/aws-sdk-go/blob/v1.44.225/aws/request/request.go
|
||||
// See THIRD-PARTY-NOTICES for original license terms
|
||||
|
||||
package v4
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Returns host from request
|
||||
func getHost(r *http.Request) string {
|
||||
if r.Host != "" {
|
||||
return r.Host
|
||||
}
|
||||
|
||||
if r.URL == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return r.URL.Host
|
||||
}
|
||||
|
||||
// Hostname returns u.Host, without any port number.
|
||||
//
|
||||
// If Host is an IPv6 literal with a port number, Hostname returns the
|
||||
// IPv6 literal without the square brackets. IPv6 literals may include
|
||||
// a zone identifier.
|
||||
//
|
||||
// Copied from the Go 1.8 standard library (net/url)
|
||||
func stripPort(hostport string) string {
|
||||
colon := strings.IndexByte(hostport, ':')
|
||||
if colon == -1 {
|
||||
return hostport
|
||||
}
|
||||
if i := strings.IndexByte(hostport, ']'); i != -1 {
|
||||
return strings.TrimPrefix(hostport[:i], "[")
|
||||
}
|
||||
return hostport[:colon]
|
||||
}
|
||||
|
||||
// Port returns the port part of u.Host, without the leading colon.
|
||||
// If u.Host doesn't contain a port, Port returns an empty string.
|
||||
//
|
||||
// Copied from the Go 1.8 standard library (net/url)
|
||||
func portOnly(hostport string) string {
|
||||
colon := strings.IndexByte(hostport, ':')
|
||||
if colon == -1 {
|
||||
return ""
|
||||
}
|
||||
if i := strings.Index(hostport, "]:"); i != -1 {
|
||||
return hostport[i+len("]:"):]
|
||||
}
|
||||
if strings.Contains(hostport, "]") {
|
||||
return ""
|
||||
}
|
||||
return hostport[colon+len(":"):]
|
||||
}
|
||||
|
||||
// Returns true if the specified URI is using the standard port
|
||||
// (i.e. port 80 for HTTP URIs or 443 for HTTPS URIs)
|
||||
func isDefaultPort(scheme, port string) bool {
|
||||
if port == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
lowerCaseScheme := strings.ToLower(scheme)
|
||||
if (lowerCaseScheme == "http" && port == "80") || (lowerCaseScheme == "https" && port == "443") {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
65
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/uri_path.go
generated
vendored
Normal file
65
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/uri_path.go
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Based on github.com/aws/aws-sdk-go by Amazon.com, Inc. with code from:
|
||||
// - github.com/aws/aws-sdk-go/blob/v1.44.225/aws/signer/v4/uri_path.go
|
||||
// - github.com/aws/aws-sdk-go/blob/v1.44.225/private/protocol/rest/build.go
|
||||
// See THIRD-PARTY-NOTICES for original license terms
|
||||
|
||||
package v4
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Whether the byte value can be sent without escaping in AWS URLs
|
||||
var noEscape [256]bool
|
||||
|
||||
func init() {
|
||||
for i := 0; i < len(noEscape); i++ {
|
||||
// AWS expects every character except these to be escaped
|
||||
noEscape[i] = (i >= 'A' && i <= 'Z') ||
|
||||
(i >= 'a' && i <= 'z') ||
|
||||
(i >= '0' && i <= '9') ||
|
||||
i == '-' ||
|
||||
i == '.' ||
|
||||
i == '_' ||
|
||||
i == '~'
|
||||
}
|
||||
}
|
||||
|
||||
func getURIPath(u *url.URL) string {
|
||||
var uri string
|
||||
|
||||
if len(u.Opaque) > 0 {
|
||||
uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/")
|
||||
} else {
|
||||
uri = u.EscapedPath()
|
||||
}
|
||||
|
||||
if len(uri) == 0 {
|
||||
uri = "/"
|
||||
}
|
||||
|
||||
return uri
|
||||
}
|
||||
|
||||
// EscapePath escapes part of a URL path in Amazon style
|
||||
func EscapePath(path string, encodeSep bool) string {
|
||||
var buf bytes.Buffer
|
||||
for i := 0; i < len(path); i++ {
|
||||
c := path[i]
|
||||
if noEscape[c] || (c == '/' && !encodeSep) {
|
||||
buf.WriteByte(c)
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "%%%02X", c)
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
421
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/v4.go
generated
vendored
Normal file
421
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/signer/v4/v4.go
generated
vendored
Normal file
@@ -0,0 +1,421 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Based on github.com/aws/aws-sdk-go by Amazon.com, Inc. with code from:
|
||||
// - github.com/aws/aws-sdk-go/blob/v1.44.225/aws/signer/v4/v4.go
|
||||
// See THIRD-PARTY-NOTICES for original license terms
|
||||
|
||||
package v4
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/internal/aws"
|
||||
"go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
authorizationHeader = "Authorization"
|
||||
authHeaderSignatureElem = "Signature="
|
||||
|
||||
authHeaderPrefix = "AWS4-HMAC-SHA256"
|
||||
timeFormat = "20060102T150405Z"
|
||||
shortTimeFormat = "20060102"
|
||||
awsV4Request = "aws4_request"
|
||||
|
||||
// emptyStringSHA256 is a SHA256 of an empty string
|
||||
emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`
|
||||
)
|
||||
|
||||
var ignoredHeaders = rules{
|
||||
excludeList{
|
||||
mapRule{
|
||||
authorizationHeader: struct{}{},
|
||||
"User-Agent": struct{}{},
|
||||
"X-Amzn-Trace-Id": struct{}{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Signer applies AWS v4 signing to given request. Use this to sign requests
|
||||
// that need to be signed with AWS V4 Signatures.
|
||||
type Signer struct {
|
||||
// The authentication credentials the request will be signed against.
|
||||
// This value must be set to sign requests.
|
||||
Credentials *credentials.Credentials
|
||||
}
|
||||
|
||||
// NewSigner returns a Signer pointer configured with the credentials provided.
|
||||
func NewSigner(credentials *credentials.Credentials) *Signer {
|
||||
v4 := &Signer{
|
||||
Credentials: credentials,
|
||||
}
|
||||
|
||||
return v4
|
||||
}
|
||||
|
||||
type signingCtx struct {
|
||||
ServiceName string
|
||||
Region string
|
||||
Request *http.Request
|
||||
Body io.ReadSeeker
|
||||
Query url.Values
|
||||
Time time.Time
|
||||
SignedHeaderVals http.Header
|
||||
|
||||
credValues credentials.Value
|
||||
|
||||
bodyDigest string
|
||||
signedHeaders string
|
||||
canonicalHeaders string
|
||||
canonicalString string
|
||||
credentialString string
|
||||
stringToSign string
|
||||
signature string
|
||||
}
|
||||
|
||||
// Sign signs AWS v4 requests with the provided body, service name, region the
|
||||
// request is made to, and time the request is signed at. The signTime allows
|
||||
// you to specify that a request is signed for the future, and cannot be
|
||||
// used until then.
|
||||
//
|
||||
// Returns a list of HTTP headers that were included in the signature or an
|
||||
// error if signing the request failed. Generally for signed requests this value
|
||||
// is not needed as the full request context will be captured by the http.Request
|
||||
// value. It is included for reference though.
|
||||
//
|
||||
// Sign will set the request's Body to be the `body` parameter passed in. If
|
||||
// the body is not already an io.ReadCloser, it will be wrapped within one. If
|
||||
// a `nil` body parameter passed to Sign, the request's Body field will be
|
||||
// also set to nil. Its important to note that this functionality will not
|
||||
// change the request's ContentLength of the request.
|
||||
//
|
||||
// Sign differs from Presign in that it will sign the request using HTTP
|
||||
// header values. This type of signing is intended for http.Request values that
|
||||
// will not be shared, or are shared in a way the header values on the request
|
||||
// will not be lost.
|
||||
//
|
||||
// The requests body is an io.ReadSeeker so the SHA256 of the body can be
|
||||
// generated. To bypass the signer computing the hash you can set the
|
||||
// "X-Amz-Content-Sha256" header with a precomputed value. The signer will
|
||||
// only compute the hash if the request header value is empty.
|
||||
func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) {
|
||||
return v4.signWithBody(r, body, service, region, signTime)
|
||||
}
|
||||
|
||||
func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) {
|
||||
ctx := &signingCtx{
|
||||
Request: r,
|
||||
Body: body,
|
||||
Query: r.URL.Query(),
|
||||
Time: signTime,
|
||||
ServiceName: service,
|
||||
Region: region,
|
||||
}
|
||||
|
||||
for key := range ctx.Query {
|
||||
sort.Strings(ctx.Query[key])
|
||||
}
|
||||
|
||||
if ctx.isRequestSigned() {
|
||||
ctx.Time = time.Now()
|
||||
}
|
||||
|
||||
var err error
|
||||
ctx.credValues, err = v4.Credentials.GetWithContext(r.Context())
|
||||
if err != nil {
|
||||
return http.Header{}, err
|
||||
}
|
||||
|
||||
ctx.sanitizeHostForHeader()
|
||||
ctx.assignAmzQueryValues()
|
||||
if err := ctx.build(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var reader io.ReadCloser
|
||||
if body != nil {
|
||||
var ok bool
|
||||
if reader, ok = body.(io.ReadCloser); !ok {
|
||||
reader = ioutil.NopCloser(body)
|
||||
}
|
||||
}
|
||||
r.Body = reader
|
||||
|
||||
return ctx.SignedHeaderVals, nil
|
||||
}
|
||||
|
||||
// sanitizeHostForHeader removes default port from host and updates request.Host
|
||||
func (ctx *signingCtx) sanitizeHostForHeader() {
|
||||
r := ctx.Request
|
||||
host := getHost(r)
|
||||
port := portOnly(host)
|
||||
if port != "" && isDefaultPort(r.URL.Scheme, port) {
|
||||
r.Host = stripPort(host)
|
||||
}
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) assignAmzQueryValues() {
|
||||
if ctx.credValues.SessionToken != "" {
|
||||
ctx.Request.Header.Set("X-Amz-Security-Token", ctx.credValues.SessionToken)
|
||||
}
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) build() error {
|
||||
ctx.buildTime() // no depends
|
||||
ctx.buildCredentialString() // no depends
|
||||
|
||||
if err := ctx.buildBodyDigest(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
unsignedHeaders := ctx.Request.Header
|
||||
|
||||
ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders)
|
||||
ctx.buildCanonicalString() // depends on canon headers / signed headers
|
||||
ctx.buildStringToSign() // depends on canon string
|
||||
ctx.buildSignature() // depends on string to sign
|
||||
|
||||
parts := []string{
|
||||
authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString,
|
||||
"SignedHeaders=" + ctx.signedHeaders,
|
||||
authHeaderSignatureElem + ctx.signature,
|
||||
}
|
||||
ctx.Request.Header.Set(authorizationHeader, strings.Join(parts, ", "))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildTime() {
|
||||
ctx.Request.Header.Set("X-Amz-Date", formatTime(ctx.Time))
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildCredentialString() {
|
||||
ctx.credentialString = buildSigningScope(ctx.Region, ctx.ServiceName, ctx.Time)
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) {
|
||||
headers := make([]string, 0, len(header)+1)
|
||||
headers = append(headers, "host")
|
||||
for k, v := range header {
|
||||
if !r.IsValid(k) {
|
||||
continue // ignored header
|
||||
}
|
||||
if ctx.SignedHeaderVals == nil {
|
||||
ctx.SignedHeaderVals = make(http.Header)
|
||||
}
|
||||
|
||||
lowerCaseKey := strings.ToLower(k)
|
||||
if _, ok := ctx.SignedHeaderVals[lowerCaseKey]; ok {
|
||||
// include additional values
|
||||
ctx.SignedHeaderVals[lowerCaseKey] = append(ctx.SignedHeaderVals[lowerCaseKey], v...)
|
||||
continue
|
||||
}
|
||||
|
||||
headers = append(headers, lowerCaseKey)
|
||||
ctx.SignedHeaderVals[lowerCaseKey] = v
|
||||
}
|
||||
sort.Strings(headers)
|
||||
|
||||
ctx.signedHeaders = strings.Join(headers, ";")
|
||||
|
||||
headerItems := make([]string, len(headers))
|
||||
for i, k := range headers {
|
||||
if k == "host" {
|
||||
if ctx.Request.Host != "" {
|
||||
headerItems[i] = "host:" + ctx.Request.Host
|
||||
} else {
|
||||
headerItems[i] = "host:" + ctx.Request.URL.Host
|
||||
}
|
||||
} else {
|
||||
headerValues := make([]string, len(ctx.SignedHeaderVals[k]))
|
||||
for i, v := range ctx.SignedHeaderVals[k] {
|
||||
headerValues[i] = strings.TrimSpace(v)
|
||||
}
|
||||
headerItems[i] = k + ":" +
|
||||
strings.Join(headerValues, ",")
|
||||
}
|
||||
}
|
||||
stripExcessSpaces(headerItems)
|
||||
ctx.canonicalHeaders = strings.Join(headerItems, "\n")
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildCanonicalString() {
|
||||
ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1)
|
||||
|
||||
uri := getURIPath(ctx.Request.URL)
|
||||
|
||||
uri = EscapePath(uri, false)
|
||||
|
||||
ctx.canonicalString = strings.Join([]string{
|
||||
ctx.Request.Method,
|
||||
uri,
|
||||
ctx.Request.URL.RawQuery,
|
||||
ctx.canonicalHeaders + "\n",
|
||||
ctx.signedHeaders,
|
||||
ctx.bodyDigest,
|
||||
}, "\n")
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildStringToSign() {
|
||||
ctx.stringToSign = strings.Join([]string{
|
||||
authHeaderPrefix,
|
||||
formatTime(ctx.Time),
|
||||
ctx.credentialString,
|
||||
hex.EncodeToString(hashSHA256([]byte(ctx.canonicalString))),
|
||||
}, "\n")
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildSignature() {
|
||||
creds := deriveSigningKey(ctx.Region, ctx.ServiceName, ctx.credValues.SecretAccessKey, ctx.Time)
|
||||
signature := hmacSHA256(creds, []byte(ctx.stringToSign))
|
||||
ctx.signature = hex.EncodeToString(signature)
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildBodyDigest() error {
|
||||
hash := ctx.Request.Header.Get("X-Amz-Content-Sha256")
|
||||
if hash == "" {
|
||||
if ctx.Body == nil {
|
||||
hash = emptyStringSHA256
|
||||
} else {
|
||||
if !aws.IsReaderSeekable(ctx.Body) {
|
||||
return fmt.Errorf("cannot use unseekable request body %T, for signed request with body", ctx.Body)
|
||||
}
|
||||
hashBytes, err := makeSha256Reader(ctx.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hash = hex.EncodeToString(hashBytes)
|
||||
}
|
||||
}
|
||||
ctx.bodyDigest = hash
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isRequestSigned returns if the request is currently signed or presigned
|
||||
func (ctx *signingCtx) isRequestSigned() bool {
|
||||
return ctx.Request.Header.Get("Authorization") != ""
|
||||
}
|
||||
|
||||
func hmacSHA256(key []byte, data []byte) []byte {
|
||||
hash := hmac.New(sha256.New, key)
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
func hashSHA256(data []byte) []byte {
|
||||
hash := sha256.New()
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
func makeSha256Reader(reader io.ReadSeeker) (hashBytes []byte, err error) {
|
||||
hash := sha256.New()
|
||||
start, err := reader.Seek(0, io.SeekCurrent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
// ensure error is return if unable to seek back to start of payload.
|
||||
_, err = reader.Seek(start, io.SeekStart)
|
||||
}()
|
||||
|
||||
// Use CopyN to avoid allocating the 32KB buffer in io.Copy for bodies
|
||||
// smaller than 32KB. Fall back to io.Copy if we fail to determine the size.
|
||||
size, err := aws.SeekerLen(reader)
|
||||
if err != nil {
|
||||
_, _ = io.Copy(hash, reader)
|
||||
} else {
|
||||
_, _ = io.CopyN(hash, reader, size)
|
||||
}
|
||||
|
||||
return hash.Sum(nil), nil
|
||||
}
|
||||
|
||||
const doubleSpace = " "
|
||||
|
||||
// stripExcessSpaces will rewrite the passed in slice's string values to not
|
||||
// contain multiple side-by-side spaces.
|
||||
func stripExcessSpaces(vals []string) {
|
||||
var j, k, l, m, spaces int
|
||||
for i, str := range vals {
|
||||
// revive:disable:empty-block
|
||||
|
||||
// Trim trailing spaces
|
||||
for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- {
|
||||
}
|
||||
|
||||
// Trim leading spaces
|
||||
for k = 0; k < j && str[k] == ' '; k++ {
|
||||
}
|
||||
|
||||
// revive:enable:empty-block
|
||||
|
||||
str = str[k : j+1]
|
||||
|
||||
// Strip multiple spaces.
|
||||
j = strings.Index(str, doubleSpace)
|
||||
if j < 0 {
|
||||
vals[i] = str
|
||||
continue
|
||||
}
|
||||
|
||||
buf := []byte(str)
|
||||
for k, m, l = j, j, len(buf); k < l; k++ {
|
||||
if buf[k] == ' ' {
|
||||
if spaces == 0 {
|
||||
// First space.
|
||||
buf[m] = buf[k]
|
||||
m++
|
||||
}
|
||||
spaces++
|
||||
} else {
|
||||
// End of multiple spaces.
|
||||
spaces = 0
|
||||
buf[m] = buf[k]
|
||||
m++
|
||||
}
|
||||
}
|
||||
|
||||
vals[i] = string(buf[:m])
|
||||
}
|
||||
}
|
||||
|
||||
func buildSigningScope(region, service string, dt time.Time) string {
|
||||
return strings.Join([]string{
|
||||
formatShortTime(dt),
|
||||
region,
|
||||
service,
|
||||
awsV4Request,
|
||||
}, "/")
|
||||
}
|
||||
|
||||
func deriveSigningKey(region, service, secretKey string, dt time.Time) []byte {
|
||||
keyDate := hmacSHA256([]byte("AWS4"+secretKey), []byte(formatShortTime(dt)))
|
||||
keyRegion := hmacSHA256(keyDate, []byte(region))
|
||||
keyService := hmacSHA256(keyRegion, []byte(service))
|
||||
signingKey := hmacSHA256(keyService, []byte(awsV4Request))
|
||||
return signingKey
|
||||
}
|
||||
|
||||
func formatShortTime(dt time.Time) string {
|
||||
return dt.UTC().Format(shortTimeFormat)
|
||||
}
|
||||
|
||||
func formatTime(dt time.Time) string {
|
||||
return dt.UTC().Format(timeFormat)
|
||||
}
|
||||
153
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/types.go
generated
vendored
Normal file
153
server/vendor/go.mongodb.org/mongo-driver/v2/internal/aws/types.go
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Based on github.com/aws/aws-sdk-go by Amazon.com, Inc. with code from:
|
||||
// - github.com/aws/aws-sdk-go/blob/v1.44.225/aws/types.go
|
||||
// See THIRD-PARTY-NOTICES for original license terms
|
||||
|
||||
package aws
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Allows the
|
||||
// SDK to accept an io.Reader that is not also an io.Seeker for unsigned
|
||||
// streaming payload API operations.
|
||||
//
|
||||
// A ReadSeekCloser wrapping an nonseekable io.Reader used in an API
|
||||
// operation's input will prevent that operation being retried in the case of
|
||||
// network errors, and cause operation requests to fail if the operation
|
||||
// requires payload signing.
|
||||
//
|
||||
// Note: If using With S3 PutObject to stream an object upload The SDK's S3
|
||||
// Upload manager (s3manager.Uploader) provides support for streaming with the
|
||||
// ability to retry network errors.
|
||||
func ReadSeekCloser(r io.Reader) ReaderSeekerCloser {
|
||||
return ReaderSeekerCloser{r}
|
||||
}
|
||||
|
||||
// ReaderSeekerCloser represents a reader that can also delegate io.Seeker and
|
||||
// io.Closer interfaces to the underlying object if they are available.
|
||||
type ReaderSeekerCloser struct {
|
||||
r io.Reader
|
||||
}
|
||||
|
||||
// IsReaderSeekable returns if the underlying reader type can be seeked. A
|
||||
// io.Reader might not actually be seekable if it is the ReaderSeekerCloser
|
||||
// type.
|
||||
func IsReaderSeekable(r io.Reader) bool {
|
||||
switch v := r.(type) {
|
||||
case ReaderSeekerCloser:
|
||||
return v.IsSeeker()
|
||||
case *ReaderSeekerCloser:
|
||||
return v.IsSeeker()
|
||||
case io.ReadSeeker:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads from the reader up to size of p. The number of bytes read, and
|
||||
// error if it occurred will be returned.
|
||||
//
|
||||
// If the reader is not an io.Reader zero bytes read, and nil error will be
|
||||
// returned.
|
||||
//
|
||||
// Performs the same functionality as io.Reader Read
|
||||
func (r ReaderSeekerCloser) Read(p []byte) (int, error) {
|
||||
switch t := r.r.(type) {
|
||||
case io.Reader:
|
||||
return t.Read(p)
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Seek sets the offset for the next Read to offset, interpreted according to
|
||||
// whence: 0 means relative to the origin of the file, 1 means relative to the
|
||||
// current offset, and 2 means relative to the end. Seek returns the new offset
|
||||
// and an error, if any.
|
||||
//
|
||||
// If the ReaderSeekerCloser is not an io.Seeker nothing will be done.
|
||||
func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) {
|
||||
switch t := r.r.(type) {
|
||||
case io.Seeker:
|
||||
return t.Seek(offset, whence)
|
||||
}
|
||||
return int64(0), nil
|
||||
}
|
||||
|
||||
// IsSeeker returns if the underlying reader is also a seeker.
|
||||
func (r ReaderSeekerCloser) IsSeeker() bool {
|
||||
_, ok := r.r.(io.Seeker)
|
||||
return ok
|
||||
}
|
||||
|
||||
// HasLen returns the length of the underlying reader if the value implements
|
||||
// the Len() int method.
|
||||
func (r ReaderSeekerCloser) HasLen() (int, bool) {
|
||||
type lenner interface {
|
||||
Len() int
|
||||
}
|
||||
|
||||
if lr, ok := r.r.(lenner); ok {
|
||||
return lr.Len(), true
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// GetLen returns the length of the bytes remaining in the underlying reader.
|
||||
// Checks first for Len(), then io.Seeker to determine the size of the
|
||||
// underlying reader.
|
||||
//
|
||||
// Will return -1 if the length cannot be determined.
|
||||
func (r ReaderSeekerCloser) GetLen() (int64, error) {
|
||||
if l, ok := r.HasLen(); ok {
|
||||
return int64(l), nil
|
||||
}
|
||||
|
||||
if s, ok := r.r.(io.Seeker); ok {
|
||||
return seekerLen(s)
|
||||
}
|
||||
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
// SeekerLen attempts to get the number of bytes remaining at the seeker's
|
||||
// current position. Returns the number of bytes remaining or error.
|
||||
func SeekerLen(s io.Seeker) (int64, error) {
|
||||
// Determine if the seeker is actually seekable. ReaderSeekerCloser
|
||||
// hides the fact that a io.Readers might not actually be seekable.
|
||||
switch v := s.(type) {
|
||||
case ReaderSeekerCloser:
|
||||
return v.GetLen()
|
||||
case *ReaderSeekerCloser:
|
||||
return v.GetLen()
|
||||
}
|
||||
|
||||
return seekerLen(s)
|
||||
}
|
||||
|
||||
func seekerLen(s io.Seeker) (int64, error) {
|
||||
curOffset, err := s.Seek(0, io.SeekCurrent)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
endOffset, err := s.Seek(0, io.SeekEnd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
_, err = s.Seek(curOffset, io.SeekStart)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return endOffset - curOffset, nil
|
||||
}
|
||||
135
server/vendor/go.mongodb.org/mongo-driver/v2/internal/binaryutil/binaryutil.go
generated
vendored
Normal file
135
server/vendor/go.mongodb.org/mongo-driver/v2/internal/binaryutil/binaryutil.go
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright (C) MongoDB, Inc. 2025-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Package binaryutil provides utility functions for working with binary data.
|
||||
package binaryutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// Append32 appends a uint32 or int32 value to dst in little-endian byte order.
|
||||
// Byte shifting is done directly to prevent overflow security errors, in
|
||||
// compliance with gosec G115.
|
||||
//
|
||||
// See: https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/encoding/binary/binary.go;l=92
|
||||
func Append32[T ~uint32 | ~int32](dst []byte, v T) []byte {
|
||||
return append(dst,
|
||||
byte(v),
|
||||
byte(v>>8),
|
||||
byte(v>>16),
|
||||
byte(v>>24),
|
||||
)
|
||||
}
|
||||
|
||||
// Append64 appends a uint64 or int64 value to dst in little-endian byte order.
|
||||
// Byte shifting is done directly to prevent overflow security errors, in
|
||||
// compliance with gosec G115.
|
||||
//
|
||||
// See: https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/encoding/binary/binary.go;l=119
|
||||
func Append64[T ~uint64 | ~int64](dst []byte, v T) []byte {
|
||||
return append(dst,
|
||||
byte(v),
|
||||
byte(v>>8),
|
||||
byte(v>>16),
|
||||
byte(v>>24),
|
||||
byte(v>>32),
|
||||
byte(v>>40),
|
||||
byte(v>>48),
|
||||
byte(v>>56),
|
||||
)
|
||||
}
|
||||
|
||||
// ReadU32 reads a uint32 from src in little-endian byte order. ReadU32 and
|
||||
// ReadI32 are separate functions to avoid unsafe casting between unsigned and
|
||||
// signed integers.
|
||||
func ReadU32(src []byte) (uint32, []byte, bool) {
|
||||
if len(src) < 4 {
|
||||
return 0, src, false
|
||||
}
|
||||
|
||||
return binary.LittleEndian.Uint32(src), src[4:], true
|
||||
}
|
||||
|
||||
// ReadI32 reads an int32 from src in little-endian byte order.
|
||||
// Byte shifting is done directly to prevent overflow security errors, in
|
||||
// compliance with gosec G115. ReadU32 and ReadI32 are separate functions to
|
||||
// avoid unsafe casting between unsigned and signed integers.
|
||||
//
|
||||
// See: https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/encoding/binary/binary.go;l=79
|
||||
func ReadI32(src []byte) (int32, []byte, bool) {
|
||||
if len(src) < 4 {
|
||||
return 0, src, false
|
||||
}
|
||||
|
||||
_ = src[3] // bounds check hint to compiler
|
||||
|
||||
value := int32(src[0]) |
|
||||
int32(src[1])<<8 |
|
||||
int32(src[2])<<16 |
|
||||
int32(src[3])<<24
|
||||
|
||||
return value, src[4:], true
|
||||
}
|
||||
|
||||
// ReadU64 reads a uint64 from src in little-endian byte order. ReadU64 and
|
||||
// ReadI64 are separate functions to avoid unsafe casting between unsigned and
|
||||
// signed integers.
|
||||
func ReadU64(src []byte) (uint64, []byte, bool) {
|
||||
if len(src) < 8 {
|
||||
return 0, src, false
|
||||
}
|
||||
|
||||
return binary.LittleEndian.Uint64(src), src[8:], true
|
||||
}
|
||||
|
||||
// ReadI64 reads an int64 from src in little-endian byte order.
|
||||
// Byte shifting is done directly to prevent overflow security errors, in
|
||||
// compliance with gosec G115. ReadU64 and ReadI64 are separate functions to
|
||||
// avoid unsafe casting between unsigned and signed integers.
|
||||
//
|
||||
// See: https://cs.opensource.google/go/go/+/refs/tags/go1.19:src/encoding/binary/binary.go;l=101
|
||||
func ReadI64(src []byte) (int64, []byte, bool) {
|
||||
if len(src) < 8 {
|
||||
return 0, src, false
|
||||
}
|
||||
|
||||
_ = src[7] // bounds check hint to compiler
|
||||
|
||||
value := int64(src[0]) |
|
||||
int64(src[1])<<8 |
|
||||
int64(src[2])<<16 |
|
||||
int64(src[3])<<24 |
|
||||
int64(src[4])<<32 |
|
||||
int64(src[5])<<40 |
|
||||
int64(src[6])<<48 |
|
||||
int64(src[7])<<56
|
||||
|
||||
return value, src[8:], true
|
||||
}
|
||||
|
||||
// ReadCStringBytes reads a null-terminated C string from src as a byte slice.
|
||||
// This is the base implementation used by ReadCString to ensure a single source
|
||||
// of truth for C string parsing logic.
|
||||
func ReadCStringBytes(src []byte) ([]byte, []byte, bool) {
|
||||
idx := bytes.IndexByte(src, 0x00)
|
||||
if idx < 0 {
|
||||
return nil, src, false
|
||||
}
|
||||
return src[:idx], src[idx+1:], true
|
||||
}
|
||||
|
||||
// ReadCString reads a null-terminated C string from src as a string.
|
||||
// It delegates to ReadCStringBytes to maintain a single source of truth for
|
||||
// C string parsing logic.
|
||||
func ReadCString(src []byte) (string, []byte, bool) {
|
||||
cstr, rem, ok := ReadCStringBytes(src)
|
||||
if !ok {
|
||||
return "", src, false
|
||||
}
|
||||
return string(cstr), rem, true
|
||||
}
|
||||
38
server/vendor/go.mongodb.org/mongo-driver/v2/internal/binaryutil/doc.go
generated
vendored
Normal file
38
server/vendor/go.mongodb.org/mongo-driver/v2/internal/binaryutil/doc.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) MongoDB, Inc. 2026-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Package binaryutil provides functions for reading binary primitives from
|
||||
// byte slices. It is used internally for BSON parsing and wire protocol
|
||||
// operations.
|
||||
//
|
||||
// The functions in this package are designed for use in BSON operations.
|
||||
// Signed integer functions (ReadI32, ReadI64) use manual bit-shifting rather
|
||||
// than encoding/binary to avoid unsafe signed/unsigned conversions and comply
|
||||
// with gosec G115. Bounds-check elimination (BCE) hints help the compiler
|
||||
// inline these functions.
|
||||
//
|
||||
// Benchmarking across different ARM64 architectures (Apple M-series)
|
||||
// revealed non-deterministic performance discrepancies between using the
|
||||
// "encoding/binary" standard library and manual bit-shifting ("straight-lining").
|
||||
//
|
||||
// Without Loss of Generality (WLOG), benchmarking observed that:
|
||||
// - On Apple M1 Pro: Standard library (ReadU32) outperformed manual
|
||||
// bit-shifting (ReadI32) by ~2x (~0.08ns vs ~0.16ns).
|
||||
// - On Apple M4 Max: Manual bit-shifting (ReadI32) outperformed the
|
||||
// standard library (ReadU32) by ~1.6x (~0.03ns vs ~0.05ns).
|
||||
//
|
||||
// Further testing showed that "straight-lining" the ReadU32 implementation
|
||||
// to match ReadI32 normalized performance to ~0.03ns on the M4 Max, even
|
||||
// though the generated assembly for both approaches is virtually equivalent.
|
||||
//
|
||||
// The generated assembly is nearly identical for both approaches. These
|
||||
// sub-nanosecond variations likely stem from microarchitecture differences
|
||||
// (instruction caching, branch prediction) rather than the code itself.
|
||||
//
|
||||
// Since network I/O dominates driver latency, these differences do not have a
|
||||
// significant impact on driver performance. The implementation favors security
|
||||
// compliance and readability over hardware-specific tuning.
|
||||
package binaryutil
|
||||
40
server/vendor/go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil/bsoncoreutil.go
generated
vendored
Normal file
40
server/vendor/go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil/bsoncoreutil.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (C) MongoDB, Inc. 2024-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncoreutil
|
||||
|
||||
// Truncate truncates a given string for a certain width
|
||||
func Truncate(str string, width int) string {
|
||||
if width <= 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
if len(str) <= width {
|
||||
return str
|
||||
}
|
||||
|
||||
// Truncate the byte slice of the string to the given width.
|
||||
newStr := str[:width]
|
||||
|
||||
// Check if the last byte is at the beginning of a multi-byte character.
|
||||
// If it is, then remove the last byte.
|
||||
if newStr[len(newStr)-1]&0xC0 == 0xC0 {
|
||||
return newStr[:len(newStr)-1]
|
||||
}
|
||||
|
||||
// Check if the last byte is a multi-byte character
|
||||
if newStr[len(newStr)-1]&0xC0 == 0x80 {
|
||||
// If it is, step back until you we are at the start of a character
|
||||
for i := len(newStr) - 1; i >= 0; i-- {
|
||||
if newStr[i]&0xC0 == 0xC0 {
|
||||
// Truncate at the end of the character before the character we stepped back to
|
||||
return newStr[:i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newStr
|
||||
}
|
||||
62
server/vendor/go.mongodb.org/mongo-driver/v2/internal/bsonutil/bsonutil.go
generated
vendored
Normal file
62
server/vendor/go.mongodb.org/mongo-driver/v2/internal/bsonutil/bsonutil.go
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsonutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
// StringSliceFromRawValue decodes the provided BSON value into a []string. This function returns an error if the value
|
||||
// is not an array or any of the elements in the array are not strings. The name parameter is used to add context to
|
||||
// error messages.
|
||||
func StringSliceFromRawValue(name string, val bson.RawValue) ([]string, error) {
|
||||
arr, ok := val.ArrayOK()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected '%s' to be an array but it's a BSON %s", name, val.Type)
|
||||
}
|
||||
|
||||
arrayValues, err := arr.Values()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
strs := make([]string, 0, len(arrayValues))
|
||||
for _, arrayVal := range arrayValues {
|
||||
str, ok := arrayVal.StringValueOK()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected '%s' to be an array of strings, but found a BSON %s", name, arrayVal.Type)
|
||||
}
|
||||
strs = append(strs, str)
|
||||
}
|
||||
return strs, nil
|
||||
}
|
||||
|
||||
// RawArrayToDocuments converts an array of documents to []bson.Raw.
|
||||
func RawArrayToDocuments(arr bson.RawArray) []bson.Raw {
|
||||
values, err := arr.Values()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error converting BSON document to values: %v", err))
|
||||
}
|
||||
|
||||
out := make([]bson.Raw, len(values))
|
||||
for i := range values {
|
||||
out[i] = values[i].Document()
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// RawToInterfaces takes one or many bson.Raw documents and returns them as a []any.
|
||||
func RawToInterfaces(docs ...bson.Raw) []any {
|
||||
out := make([]any, len(docs))
|
||||
for i := range docs {
|
||||
out[i] = docs[i]
|
||||
}
|
||||
return out
|
||||
}
|
||||
64
server/vendor/go.mongodb.org/mongo-driver/v2/internal/codecutil/encoding.go
generated
vendored
Normal file
64
server/vendor/go.mongodb.org/mongo-driver/v2/internal/codecutil/encoding.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package codecutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
"go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
|
||||
)
|
||||
|
||||
var ErrNilValue = errors.New("value is nil")
|
||||
|
||||
// MarshalError is returned when attempting to transform a value into a document
|
||||
// results in an error.
|
||||
type MarshalError struct {
|
||||
Value any
|
||||
Err error
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e MarshalError) Error() string {
|
||||
return fmt.Sprintf("cannot marshal type %q to a BSON Document: %v",
|
||||
reflect.TypeOf(e.Value), e.Err)
|
||||
}
|
||||
|
||||
func (e MarshalError) Unwrap() error { return e.Err }
|
||||
|
||||
// EncoderFn is used to functionally construct an encoder for marshaling values.
|
||||
type EncoderFn func(io.Writer) *bson.Encoder
|
||||
|
||||
// MarshalValue will attempt to encode the value with the encoder returned by
|
||||
// the encoder function.
|
||||
func MarshalValue(val any, encFn EncoderFn) (bsoncore.Value, error) {
|
||||
// If the val is already a bsoncore.Value, then do nothing.
|
||||
if bval, ok := val.(bsoncore.Value); ok {
|
||||
return bval, nil
|
||||
}
|
||||
|
||||
if val == nil {
|
||||
return bsoncore.Value{}, ErrNilValue
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
enc := encFn(buf)
|
||||
|
||||
// Encode the value in a single-element document with an empty key. Use
|
||||
// bsoncore to extract the first element and return the BSON value.
|
||||
err := enc.Encode(bson.D{{Key: "", Value: val}})
|
||||
if err != nil {
|
||||
return bsoncore.Value{}, MarshalError{Value: val, Err: err}
|
||||
}
|
||||
|
||||
return bsoncore.Document(buf.Bytes()).Index(0).Value(), nil
|
||||
}
|
||||
148
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/assume_role_provider.go
generated
vendored
Normal file
148
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/assume_role_provider.go
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package credproviders
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
|
||||
"go.mongodb.org/mongo-driver/v2/internal/uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
// assumeRoleProviderName provides a name of assume role provider
|
||||
assumeRoleProviderName = "AssumeRoleProvider"
|
||||
|
||||
stsURI = `https://sts.amazonaws.com/?Action=AssumeRoleWithWebIdentity&RoleSessionName=%s&RoleArn=%s&WebIdentityToken=%s&Version=2011-06-15`
|
||||
)
|
||||
|
||||
// An AssumeRoleProvider retrieves credentials for assume role with web identity.
|
||||
type AssumeRoleProvider struct {
|
||||
AwsRoleArnEnv EnvVar
|
||||
AwsWebIdentityTokenFileEnv EnvVar
|
||||
AwsRoleSessionNameEnv EnvVar
|
||||
|
||||
httpClient *http.Client
|
||||
expiration time.Time
|
||||
|
||||
// expiryWindow will allow the credentials to trigger refreshing prior to the credentials actually expiring.
|
||||
// This is beneficial so expiring credentials do not cause request to fail unexpectedly due to exceptions.
|
||||
//
|
||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
||||
// 10 seconds before the credentials are actually expired.
|
||||
expiryWindow time.Duration
|
||||
}
|
||||
|
||||
// NewAssumeRoleProvider returns a pointer to an assume role provider.
|
||||
func NewAssumeRoleProvider(httpClient *http.Client, expiryWindow time.Duration) *AssumeRoleProvider {
|
||||
return &AssumeRoleProvider{
|
||||
// AwsRoleArnEnv is the environment variable for AWS_ROLE_ARN
|
||||
AwsRoleArnEnv: EnvVar("AWS_ROLE_ARN"),
|
||||
// AwsWebIdentityTokenFileEnv is the environment variable for AWS_WEB_IDENTITY_TOKEN_FILE
|
||||
AwsWebIdentityTokenFileEnv: EnvVar("AWS_WEB_IDENTITY_TOKEN_FILE"),
|
||||
// AwsRoleSessionNameEnv is the environment variable for AWS_ROLE_SESSION_NAME
|
||||
AwsRoleSessionNameEnv: EnvVar("AWS_ROLE_SESSION_NAME"),
|
||||
httpClient: httpClient,
|
||||
expiryWindow: expiryWindow,
|
||||
}
|
||||
}
|
||||
|
||||
// RetrieveWithContext retrieves the keys from the AWS service.
|
||||
func (a *AssumeRoleProvider) RetrieveWithContext(ctx context.Context) (credentials.Value, error) {
|
||||
const defaultHTTPTimeout = 10 * time.Second
|
||||
|
||||
v := credentials.Value{ProviderName: assumeRoleProviderName}
|
||||
|
||||
roleArn := a.AwsRoleArnEnv.Get()
|
||||
tokenFile := a.AwsWebIdentityTokenFileEnv.Get()
|
||||
if tokenFile == "" && roleArn == "" {
|
||||
return v, errors.New("AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN are missing")
|
||||
}
|
||||
if tokenFile != "" && roleArn == "" {
|
||||
return v, errors.New("AWS_WEB_IDENTITY_TOKEN_FILE is set, but AWS_ROLE_ARN is missing")
|
||||
}
|
||||
if tokenFile == "" && roleArn != "" {
|
||||
return v, errors.New("AWS_ROLE_ARN is set, but AWS_WEB_IDENTITY_TOKEN_FILE is missing")
|
||||
}
|
||||
token, err := ioutil.ReadFile(tokenFile)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
|
||||
sessionName := a.AwsRoleSessionNameEnv.Get()
|
||||
if sessionName == "" {
|
||||
// Use a UUID if the RoleSessionName is not given.
|
||||
id, err := uuid.New()
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
sessionName = id.String()
|
||||
}
|
||||
|
||||
fullURI := fmt.Sprintf(stsURI, sessionName, roleArn, string(token))
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, fullURI, nil)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultHTTPTimeout)
|
||||
defer cancel()
|
||||
resp, err := a.httpClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return v, fmt.Errorf("response failure: %s", resp.Status)
|
||||
}
|
||||
|
||||
var stsResp struct {
|
||||
Response struct {
|
||||
Result struct {
|
||||
Credentials struct {
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SecretAccessKey string `json:"SecretAccessKey"`
|
||||
Token string `json:"SessionToken"`
|
||||
Expiration float64 `json:"Expiration"`
|
||||
} `json:"Credentials"`
|
||||
} `json:"AssumeRoleWithWebIdentityResult"`
|
||||
} `json:"AssumeRoleWithWebIdentityResponse"`
|
||||
}
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&stsResp)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
v.AccessKeyID = stsResp.Response.Result.Credentials.AccessKeyID
|
||||
v.SecretAccessKey = stsResp.Response.Result.Credentials.SecretAccessKey
|
||||
v.SessionToken = stsResp.Response.Result.Credentials.Token
|
||||
if !v.HasKeys() {
|
||||
return v, errors.New("failed to retrieve web identity keys")
|
||||
}
|
||||
sec := int64(stsResp.Response.Result.Credentials.Expiration)
|
||||
a.expiration = time.Unix(sec, 0).Add(-a.expiryWindow)
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Retrieve retrieves the keys from the AWS service.
|
||||
func (a *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
|
||||
return a.RetrieveWithContext(context.Background())
|
||||
}
|
||||
|
||||
// IsExpired returns true if the credentials are expired.
|
||||
func (a *AssumeRoleProvider) IsExpired() bool {
|
||||
return a.expiration.Before(time.Now())
|
||||
}
|
||||
183
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ec2_provider.go
generated
vendored
Normal file
183
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ec2_provider.go
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package credproviders
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
// ec2ProviderName provides a name of EC2 provider
|
||||
ec2ProviderName = "EC2Provider"
|
||||
|
||||
awsEC2URI = "http://169.254.169.254/"
|
||||
awsEC2RolePath = "latest/meta-data/iam/security-credentials/"
|
||||
awsEC2TokenPath = "latest/api/token"
|
||||
|
||||
defaultHTTPTimeout = 10 * time.Second
|
||||
)
|
||||
|
||||
// An EC2Provider retrieves credentials from EC2 metadata.
|
||||
type EC2Provider struct {
|
||||
httpClient *http.Client
|
||||
expiration time.Time
|
||||
|
||||
// expiryWindow will allow the credentials to trigger refreshing prior to the credentials actually expiring.
|
||||
// This is beneficial so expiring credentials do not cause request to fail unexpectedly due to exceptions.
|
||||
//
|
||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
||||
// 10 seconds before the credentials are actually expired.
|
||||
expiryWindow time.Duration
|
||||
}
|
||||
|
||||
// NewEC2Provider returns a pointer to an EC2 credential provider.
|
||||
func NewEC2Provider(httpClient *http.Client, expiryWindow time.Duration) *EC2Provider {
|
||||
return &EC2Provider{
|
||||
httpClient: httpClient,
|
||||
expiryWindow: expiryWindow,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EC2Provider) getToken(ctx context.Context) (string, error) {
|
||||
req, err := http.NewRequest(http.MethodPut, awsEC2URI+awsEC2TokenPath, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
const defaultEC2TTLSeconds = "30"
|
||||
req.Header.Set("X-aws-ec2-metadata-token-ttl-seconds", defaultEC2TTLSeconds)
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultHTTPTimeout)
|
||||
defer cancel()
|
||||
resp, err := e.httpClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("%s %s failed: %s", req.Method, req.URL.String(), resp.Status)
|
||||
}
|
||||
|
||||
token, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(token) == 0 {
|
||||
return "", errors.New("unable to retrieve token from EC2 metadata")
|
||||
}
|
||||
return string(token), nil
|
||||
}
|
||||
|
||||
func (e *EC2Provider) getRoleName(ctx context.Context, token string) (string, error) {
|
||||
req, err := http.NewRequest(http.MethodGet, awsEC2URI+awsEC2RolePath, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("X-aws-ec2-metadata-token", token)
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultHTTPTimeout)
|
||||
defer cancel()
|
||||
resp, err := e.httpClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("%s %s failed: %s", req.Method, req.URL.String(), resp.Status)
|
||||
}
|
||||
|
||||
role, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(role) == 0 {
|
||||
return "", errors.New("unable to retrieve role_name from EC2 metadata")
|
||||
}
|
||||
return string(role), nil
|
||||
}
|
||||
|
||||
func (e *EC2Provider) getCredentials(ctx context.Context, token string, role string) (credentials.Value, time.Time, error) {
|
||||
v := credentials.Value{ProviderName: ec2ProviderName}
|
||||
|
||||
pathWithRole := awsEC2URI + awsEC2RolePath + role
|
||||
req, err := http.NewRequest(http.MethodGet, pathWithRole, nil)
|
||||
if err != nil {
|
||||
return v, time.Time{}, err
|
||||
}
|
||||
req.Header.Set("X-aws-ec2-metadata-token", token)
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultHTTPTimeout)
|
||||
defer cancel()
|
||||
resp, err := e.httpClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return v, time.Time{}, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return v, time.Time{}, fmt.Errorf("%s %s failed: %s", req.Method, req.URL.String(), resp.Status)
|
||||
}
|
||||
|
||||
var ec2Resp struct {
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SecretAccessKey string `json:"SecretAccessKey"`
|
||||
Token string `json:"Token"`
|
||||
Expiration time.Time `json:"Expiration"`
|
||||
}
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&ec2Resp)
|
||||
if err != nil {
|
||||
return v, time.Time{}, err
|
||||
}
|
||||
|
||||
v.AccessKeyID = ec2Resp.AccessKeyID
|
||||
v.SecretAccessKey = ec2Resp.SecretAccessKey
|
||||
v.SessionToken = ec2Resp.Token
|
||||
|
||||
return v, ec2Resp.Expiration, nil
|
||||
}
|
||||
|
||||
// RetrieveWithContext retrieves the keys from the AWS service.
|
||||
func (e *EC2Provider) RetrieveWithContext(ctx context.Context) (credentials.Value, error) {
|
||||
v := credentials.Value{ProviderName: ec2ProviderName}
|
||||
|
||||
token, err := e.getToken(ctx)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
|
||||
role, err := e.getRoleName(ctx, token)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
|
||||
v, exp, err := e.getCredentials(ctx, token, role)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
if !v.HasKeys() {
|
||||
return v, errors.New("failed to retrieve EC2 keys")
|
||||
}
|
||||
e.expiration = exp.Add(-e.expiryWindow)
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Retrieve retrieves the keys from the AWS service.
|
||||
func (e *EC2Provider) Retrieve() (credentials.Value, error) {
|
||||
return e.RetrieveWithContext(context.Background())
|
||||
}
|
||||
|
||||
// IsExpired returns true if the credentials are expired.
|
||||
func (e *EC2Provider) IsExpired() bool {
|
||||
return e.expiration.Before(time.Now())
|
||||
}
|
||||
112
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ecs_provider.go
generated
vendored
Normal file
112
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/ecs_provider.go
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package credproviders
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
// ecsProviderName provides a name of ECS provider
|
||||
ecsProviderName = "ECSProvider"
|
||||
|
||||
awsRelativeURI = "http://169.254.170.2/"
|
||||
)
|
||||
|
||||
// An ECSProvider retrieves credentials from ECS metadata.
|
||||
type ECSProvider struct {
|
||||
AwsContainerCredentialsRelativeURIEnv EnvVar
|
||||
|
||||
httpClient *http.Client
|
||||
expiration time.Time
|
||||
|
||||
// expiryWindow will allow the credentials to trigger refreshing prior to the credentials actually expiring.
|
||||
// This is beneficial so expiring credentials do not cause request to fail unexpectedly due to exceptions.
|
||||
//
|
||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
||||
// 10 seconds before the credentials are actually expired.
|
||||
expiryWindow time.Duration
|
||||
}
|
||||
|
||||
// NewECSProvider returns a pointer to an ECS credential provider.
|
||||
func NewECSProvider(httpClient *http.Client, expiryWindow time.Duration) *ECSProvider {
|
||||
return &ECSProvider{
|
||||
// AwsContainerCredentialsRelativeURIEnv is the environment variable for AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
|
||||
AwsContainerCredentialsRelativeURIEnv: EnvVar("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"),
|
||||
httpClient: httpClient,
|
||||
expiryWindow: expiryWindow,
|
||||
}
|
||||
}
|
||||
|
||||
// RetrieveWithContext retrieves the keys from the AWS service.
|
||||
func (e *ECSProvider) RetrieveWithContext(ctx context.Context) (credentials.Value, error) {
|
||||
const defaultHTTPTimeout = 10 * time.Second
|
||||
|
||||
v := credentials.Value{ProviderName: ecsProviderName}
|
||||
|
||||
relativeEcsURI := e.AwsContainerCredentialsRelativeURIEnv.Get()
|
||||
if len(relativeEcsURI) == 0 {
|
||||
return v, errors.New("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI is missing")
|
||||
}
|
||||
fullURI := awsRelativeURI + relativeEcsURI
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, fullURI, nil)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, defaultHTTPTimeout)
|
||||
defer cancel()
|
||||
resp, err := e.httpClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return v, fmt.Errorf("response failure: %s", resp.Status)
|
||||
}
|
||||
|
||||
var ecsResp struct {
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SecretAccessKey string `json:"SecretAccessKey"`
|
||||
Token string `json:"Token"`
|
||||
Expiration time.Time `json:"Expiration"`
|
||||
}
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&ecsResp)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
|
||||
v.AccessKeyID = ecsResp.AccessKeyID
|
||||
v.SecretAccessKey = ecsResp.SecretAccessKey
|
||||
v.SessionToken = ecsResp.Token
|
||||
if !v.HasKeys() {
|
||||
return v, errors.New("failed to retrieve ECS keys")
|
||||
}
|
||||
e.expiration = ecsResp.Expiration.Add(-e.expiryWindow)
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Retrieve retrieves the keys from the AWS service.
|
||||
func (e *ECSProvider) Retrieve() (credentials.Value, error) {
|
||||
return e.RetrieveWithContext(context.Background())
|
||||
}
|
||||
|
||||
// IsExpired returns true if the credentials are expired.
|
||||
func (e *ECSProvider) IsExpired() bool {
|
||||
return e.expiration.Before(time.Now())
|
||||
}
|
||||
69
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/env_provider.go
generated
vendored
Normal file
69
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/env_provider.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package credproviders
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
|
||||
)
|
||||
|
||||
// envProviderName provides a name of Env provider
|
||||
const envProviderName = "EnvProvider"
|
||||
|
||||
// EnvVar is an environment variable
|
||||
type EnvVar string
|
||||
|
||||
// Get retrieves the environment variable
|
||||
func (ev EnvVar) Get() string {
|
||||
return os.Getenv(string(ev))
|
||||
}
|
||||
|
||||
// A EnvProvider retrieves credentials from the environment variables of the
|
||||
// running process. Environment credentials never expire.
|
||||
type EnvProvider struct {
|
||||
AwsAccessKeyIDEnv EnvVar
|
||||
AwsSecretAccessKeyEnv EnvVar
|
||||
AwsSessionTokenEnv EnvVar
|
||||
|
||||
retrieved bool
|
||||
}
|
||||
|
||||
// NewEnvProvider returns a pointer to an ECS credential provider.
|
||||
func NewEnvProvider() *EnvProvider {
|
||||
return &EnvProvider{
|
||||
// AwsAccessKeyIDEnv is the environment variable for AWS_ACCESS_KEY_ID
|
||||
AwsAccessKeyIDEnv: EnvVar("AWS_ACCESS_KEY_ID"),
|
||||
// AwsSecretAccessKeyEnv is the environment variable for AWS_SECRET_ACCESS_KEY
|
||||
AwsSecretAccessKeyEnv: EnvVar("AWS_SECRET_ACCESS_KEY"),
|
||||
// AwsSessionTokenEnv is the environment variable for AWS_SESSION_TOKEN
|
||||
AwsSessionTokenEnv: EnvVar("AWS_SESSION_TOKEN"),
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve retrieves the keys from the environment.
|
||||
func (e *EnvProvider) Retrieve() (credentials.Value, error) {
|
||||
e.retrieved = false
|
||||
|
||||
v := credentials.Value{
|
||||
AccessKeyID: e.AwsAccessKeyIDEnv.Get(),
|
||||
SecretAccessKey: e.AwsSecretAccessKeyEnv.Get(),
|
||||
SessionToken: e.AwsSessionTokenEnv.Get(),
|
||||
ProviderName: envProviderName,
|
||||
}
|
||||
err := verify(v)
|
||||
if err == nil {
|
||||
e.retrieved = true
|
||||
}
|
||||
|
||||
return v, err
|
||||
}
|
||||
|
||||
// IsExpired returns true if the credentials have not been retrieved.
|
||||
func (e *EnvProvider) IsExpired() bool {
|
||||
return !e.retrieved
|
||||
}
|
||||
103
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/imds_provider.go
generated
vendored
Normal file
103
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/imds_provider.go
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package credproviders
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
|
||||
)
|
||||
|
||||
const (
|
||||
// AzureProviderName provides a name of Azure provider
|
||||
AzureProviderName = "AzureProvider"
|
||||
|
||||
azureURI = "http://169.254.169.254/metadata/identity/oauth2/token"
|
||||
)
|
||||
|
||||
// An AzureProvider retrieves credentials from Azure IMDS.
|
||||
type AzureProvider struct {
|
||||
httpClient *http.Client
|
||||
expiration time.Time
|
||||
expiryWindow time.Duration
|
||||
}
|
||||
|
||||
// NewAzureProvider returns a pointer to an Azure credential provider.
|
||||
func NewAzureProvider(httpClient *http.Client, expiryWindow time.Duration) *AzureProvider {
|
||||
return &AzureProvider{
|
||||
httpClient: httpClient,
|
||||
expiration: time.Time{},
|
||||
expiryWindow: expiryWindow,
|
||||
}
|
||||
}
|
||||
|
||||
// RetrieveWithContext retrieves the keys from the Azure service.
|
||||
func (a *AzureProvider) RetrieveWithContext(ctx context.Context) (credentials.Value, error) {
|
||||
v := credentials.Value{ProviderName: AzureProviderName}
|
||||
req, err := http.NewRequest(http.MethodGet, azureURI, nil)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("unable to retrieve Azure credentials: %w", err)
|
||||
}
|
||||
q := make(url.Values)
|
||||
q.Set("api-version", "2018-02-01")
|
||||
q.Set("resource", "https://vault.azure.net")
|
||||
req.URL.RawQuery = q.Encode()
|
||||
req.Header.Set("Metadata", "true")
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
resp, err := a.httpClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("unable to retrieve Azure credentials: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("unable to retrieve Azure credentials: error reading response body: %w", err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return v, fmt.Errorf("unable to retrieve Azure credentials: expected StatusCode 200, got StatusCode: %v. Response body: %s", resp.StatusCode, body)
|
||||
}
|
||||
var tokenResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn string `json:"expires_in"`
|
||||
}
|
||||
// Attempt to read body as JSON
|
||||
err = json.Unmarshal(body, &tokenResponse)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("unable to retrieve Azure credentials: error reading body JSON: %w (response body: %s)", err, body)
|
||||
}
|
||||
if tokenResponse.AccessToken == "" {
|
||||
return v, fmt.Errorf("unable to retrieve Azure credentials: got unexpected empty accessToken from Azure Metadata Server. Response body: %s", body)
|
||||
}
|
||||
v.SessionToken = tokenResponse.AccessToken
|
||||
|
||||
expiresIn, err := time.ParseDuration(tokenResponse.ExpiresIn + "s")
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
if expiration := expiresIn - a.expiryWindow; expiration > 0 {
|
||||
a.expiration = time.Now().Add(expiration)
|
||||
}
|
||||
|
||||
return v, err
|
||||
}
|
||||
|
||||
// Retrieve retrieves the keys from the Azure service.
|
||||
func (a *AzureProvider) Retrieve() (credentials.Value, error) {
|
||||
return a.RetrieveWithContext(context.Background())
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials have been retrieved.
|
||||
func (a *AzureProvider) IsExpired() bool {
|
||||
return a.expiration.Before(time.Now())
|
||||
}
|
||||
58
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/static_provider.go
generated
vendored
Normal file
58
server/vendor/go.mongodb.org/mongo-driver/v2/internal/credproviders/static_provider.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package credproviders
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/internal/aws/credentials"
|
||||
)
|
||||
|
||||
// staticProviderName provides a name of Static provider
|
||||
const staticProviderName = "StaticProvider"
|
||||
|
||||
// A StaticProvider is a set of credentials which are set programmatically,
|
||||
// and will never expire.
|
||||
type StaticProvider struct {
|
||||
credentials.Value
|
||||
|
||||
verified bool
|
||||
err error
|
||||
}
|
||||
|
||||
func verify(v credentials.Value) error {
|
||||
if !v.HasKeys() {
|
||||
return errors.New("failed to retrieve ACCESS_KEY_ID and SECRET_ACCESS_KEY")
|
||||
}
|
||||
if v.AccessKeyID != "" && v.SecretAccessKey == "" {
|
||||
return errors.New("ACCESS_KEY_ID is set, but SECRET_ACCESS_KEY is missing")
|
||||
}
|
||||
if v.AccessKeyID == "" && v.SecretAccessKey != "" {
|
||||
return errors.New("SECRET_ACCESS_KEY is set, but ACCESS_KEY_ID is missing")
|
||||
}
|
||||
if v.AccessKeyID == "" && v.SecretAccessKey == "" && v.SessionToken != "" {
|
||||
return errors.New("AWS_SESSION_TOKEN is set, but ACCESS_KEY_ID and SECRET_ACCESS_KEY are missing")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Retrieve returns the credentials or error if the credentials are invalid.
|
||||
func (s *StaticProvider) Retrieve() (credentials.Value, error) {
|
||||
if !s.verified {
|
||||
s.err = verify(s.Value)
|
||||
s.ProviderName = staticProviderName
|
||||
s.verified = true
|
||||
}
|
||||
return s.Value, s.err
|
||||
}
|
||||
|
||||
// IsExpired returns if the credentials are expired.
|
||||
//
|
||||
// For StaticProvider, the credentials never expired.
|
||||
func (s *StaticProvider) IsExpired() bool {
|
||||
return false
|
||||
}
|
||||
40
server/vendor/go.mongodb.org/mongo-driver/v2/internal/csfle/csfle.go
generated
vendored
Normal file
40
server/vendor/go.mongodb.org/mongo-driver/v2/internal/csfle/csfle.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (C) MongoDB, Inc. 2022-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package csfle
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
|
||||
)
|
||||
|
||||
const (
|
||||
EncryptedCacheCollection = "ecc"
|
||||
EncryptedStateCollection = "esc"
|
||||
EncryptedCompactionCollection = "ecoc"
|
||||
)
|
||||
|
||||
// GetEncryptedStateCollectionName returns the encrypted state collection name associated with dataCollectionName.
|
||||
func GetEncryptedStateCollectionName(efBSON bsoncore.Document, dataCollectionName string, stateCollection string) (string, error) {
|
||||
fieldName := stateCollection + "Collection"
|
||||
val, err := efBSON.LookupErr(fieldName)
|
||||
if err != nil {
|
||||
if !errors.Is(err, bsoncore.ErrElementNotFound) {
|
||||
return "", err
|
||||
}
|
||||
// Return default name.
|
||||
defaultName := "enxcol_." + dataCollectionName + "." + stateCollection
|
||||
return defaultName, nil
|
||||
}
|
||||
|
||||
stateCollectionName, ok := val.StringValueOK()
|
||||
if !ok {
|
||||
return "", fmt.Errorf("expected string for '%v', got: %v", fieldName, val.Type)
|
||||
}
|
||||
return stateCollectionName, nil
|
||||
}
|
||||
106
server/vendor/go.mongodb.org/mongo-driver/v2/internal/csot/csot.go
generated
vendored
Normal file
106
server/vendor/go.mongodb.org/mongo-driver/v2/internal/csot/csot.go
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright (C) MongoDB, Inc. 2022-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package csot
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
type clientLevel struct{}
|
||||
|
||||
func isClientLevel(ctx context.Context) bool {
|
||||
val := ctx.Value(clientLevel{})
|
||||
if val == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return val.(bool)
|
||||
}
|
||||
|
||||
// IsTimeoutContext checks if the provided context has been assigned a deadline
|
||||
// or has unlimited retries.
|
||||
func IsTimeoutContext(ctx context.Context) bool {
|
||||
_, ok := ctx.Deadline()
|
||||
|
||||
return ok || isClientLevel(ctx)
|
||||
}
|
||||
|
||||
// WithTimeout will set the given timeout on the context, if no deadline has
|
||||
// already been set.
|
||||
//
|
||||
// This function assumes that the timeout field is static, given that the
|
||||
// timeout should be sourced from the client. Therefore, once a timeout function
|
||||
// parameter has been applied to the context, it will remain for the lifetime
|
||||
// of the context.
|
||||
func WithTimeout(parent context.Context, timeout *time.Duration) (context.Context, context.CancelFunc) {
|
||||
cancel := func() {}
|
||||
|
||||
if timeout == nil || IsTimeoutContext(parent) {
|
||||
// In the following conditions, do nothing:
|
||||
// 1. The parent already has a deadline
|
||||
// 2. The parent does not have a deadline, but a client-level timeout has
|
||||
// been applied.
|
||||
// 3. The parent does not have a deadline, there is not client-level
|
||||
// timeout, and the timeout parameter DNE.
|
||||
return parent, cancel
|
||||
}
|
||||
|
||||
// If a client-level timeout has not been applied, then apply it.
|
||||
parent = context.WithValue(parent, clientLevel{}, true)
|
||||
|
||||
dur := *timeout
|
||||
|
||||
if dur == 0 {
|
||||
// If the parent does not have a deadline and the timeout is zero, then
|
||||
// do nothing.
|
||||
return parent, cancel
|
||||
}
|
||||
|
||||
// If the parent does not have a dealine and the timeout is non-zero, then
|
||||
// apply the timeout.
|
||||
return context.WithTimeout(parent, dur)
|
||||
}
|
||||
|
||||
// WithServerSelectionTimeout creates a context with a timeout that is the
|
||||
// minimum of serverSelectionTimeoutMS and context deadline. The usage of
|
||||
// non-positive values for serverSelectionTimeoutMS are an anti-pattern and are
|
||||
// not considered in this calculation.
|
||||
func WithServerSelectionTimeout(
|
||||
parent context.Context,
|
||||
serverSelectionTimeout time.Duration,
|
||||
) (context.Context, context.CancelFunc) {
|
||||
if serverSelectionTimeout <= 0 {
|
||||
return parent, func() {}
|
||||
}
|
||||
|
||||
return context.WithTimeout(parent, serverSelectionTimeout)
|
||||
}
|
||||
|
||||
// ZeroRTTMonitor implements the RTTMonitor interface and is used internally for testing. It returns 0 for all
|
||||
// RTT calculations and an empty string for RTT statistics.
|
||||
type ZeroRTTMonitor struct{}
|
||||
|
||||
// EWMA implements the RTT monitor interface.
|
||||
func (zrm *ZeroRTTMonitor) EWMA() time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Min implements the RTT monitor interface.
|
||||
func (zrm *ZeroRTTMonitor) Min() time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
||||
// P90 implements the RTT monitor interface.
|
||||
func (zrm *ZeroRTTMonitor) P90() time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Stats implements the RTT monitor interface.
|
||||
func (zrm *ZeroRTTMonitor) Stats() string {
|
||||
return ""
|
||||
}
|
||||
117
server/vendor/go.mongodb.org/mongo-driver/v2/internal/decimal128/decimal128.go
generated
vendored
Normal file
117
server/vendor/go.mongodb.org/mongo-driver/v2/internal/decimal128/decimal128.go
generated
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package decimal128
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// These constants are the maximum and minimum values for the exponent field in a decimal128 value.
|
||||
const (
|
||||
MaxDecimal128Exp = 6111
|
||||
MinDecimal128Exp = -6176
|
||||
)
|
||||
|
||||
func divmod(h, l uint64, div uint32) (qh, ql uint64, rem uint32) {
|
||||
div64 := uint64(div)
|
||||
a := h >> 32
|
||||
aq := a / div64
|
||||
ar := a % div64
|
||||
b := ar<<32 + h&(1<<32-1)
|
||||
bq := b / div64
|
||||
br := b % div64
|
||||
c := br<<32 + l>>32
|
||||
cq := c / div64
|
||||
cr := c % div64
|
||||
d := cr<<32 + l&(1<<32-1)
|
||||
dq := d / div64
|
||||
dr := d % div64
|
||||
return (aq<<32 | bq), (cq<<32 | dq), uint32(dr)
|
||||
}
|
||||
|
||||
// String returns a string representation of the decimal value.
|
||||
func String(h, l uint64) string {
|
||||
var posSign int // positive sign
|
||||
var exp int // exponent
|
||||
var high, low uint64 // significand high/low
|
||||
|
||||
if h>>63&1 == 0 {
|
||||
posSign = 1
|
||||
}
|
||||
|
||||
switch h >> 58 & (1<<5 - 1) {
|
||||
case 0x1F:
|
||||
return "NaN"
|
||||
case 0x1E:
|
||||
return "-Infinity"[posSign:]
|
||||
}
|
||||
|
||||
low = l
|
||||
if h>>61&3 == 3 {
|
||||
// Bits: 1*sign 2*ignored 14*exponent 111*significand.
|
||||
// Implicit 0b100 prefix in significand.
|
||||
exp = int(h >> 47 & (1<<14 - 1))
|
||||
// Spec says all of these values are out of range.
|
||||
high, low = 0, 0
|
||||
} else {
|
||||
// Bits: 1*sign 14*exponent 113*significand
|
||||
exp = int(h >> 49 & (1<<14 - 1))
|
||||
high = h & (1<<49 - 1)
|
||||
}
|
||||
exp += MinDecimal128Exp
|
||||
|
||||
// Would be handled by the logic below, but that's trivial and common.
|
||||
if high == 0 && low == 0 && exp == 0 {
|
||||
return "-0"[posSign:]
|
||||
}
|
||||
|
||||
var repr [48]byte // Loop 5 times over 9 digits plus dot, negative sign, and leading zero.
|
||||
last := len(repr)
|
||||
i := len(repr)
|
||||
dot := len(repr) + exp
|
||||
var rem uint32
|
||||
Loop:
|
||||
for d9 := 0; d9 < 5; d9++ {
|
||||
high, low, rem = divmod(high, low, 1e9)
|
||||
for d1 := 0; d1 < 9; d1++ {
|
||||
// Handle "-0.0", "0.00123400", "-1.00E-6", "1.050E+3", etc.
|
||||
if i < len(repr) && (dot == i || low == 0 && high == 0 && rem > 0 && rem < 10 && (dot < i-6 || exp > 0)) {
|
||||
exp += len(repr) - i
|
||||
i--
|
||||
repr[i] = '.'
|
||||
last = i - 1
|
||||
dot = len(repr) // Unmark.
|
||||
}
|
||||
c := '0' + byte(rem%10)
|
||||
rem /= 10
|
||||
i--
|
||||
repr[i] = c
|
||||
// Handle "0E+3", "1E+3", etc.
|
||||
if low == 0 && high == 0 && rem == 0 && i == len(repr)-1 && (dot < i-5 || exp > 0) {
|
||||
last = i
|
||||
break Loop
|
||||
}
|
||||
if c != '0' {
|
||||
last = i
|
||||
}
|
||||
// Break early. Works without it, but why.
|
||||
if dot > i && low == 0 && high == 0 && rem == 0 {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
repr[last-1] = '-'
|
||||
last--
|
||||
|
||||
if exp > 0 {
|
||||
return string(repr[last+posSign:]) + "E+" + strconv.Itoa(exp)
|
||||
}
|
||||
if exp < 0 {
|
||||
return string(repr[last+posSign:]) + "E" + strconv.Itoa(exp)
|
||||
}
|
||||
return string(repr[last+posSign:])
|
||||
}
|
||||
493
server/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/description.go
generated
vendored
Normal file
493
server/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/description.go
generated
vendored
Normal file
@@ -0,0 +1,493 @@
|
||||
// Copyright (C) MongoDB, Inc. 2024-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package driverutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
"go.mongodb.org/mongo-driver/v2/internal/bsonutil"
|
||||
"go.mongodb.org/mongo-driver/v2/internal/handshake"
|
||||
"go.mongodb.org/mongo-driver/v2/internal/ptrutil"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo/address"
|
||||
"go.mongodb.org/mongo-driver/v2/tag"
|
||||
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
|
||||
)
|
||||
|
||||
const (
|
||||
MinWireVersion = 8
|
||||
MaxWireVersion = 25
|
||||
)
|
||||
|
||||
func equalWireVersion(wv1, wv2 *description.VersionRange) bool {
|
||||
if wv1 == nil && wv2 == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if wv1 == nil || wv2 == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return wv1.Min == wv2.Min && wv1.Max == wv2.Max
|
||||
}
|
||||
|
||||
// EqualServers compares two server descriptions and returns true if they are
|
||||
// equal.
|
||||
func EqualServers(srv1, srv2 description.Server) bool {
|
||||
if srv1.CanonicalAddr.String() != srv2.CanonicalAddr.String() {
|
||||
return false
|
||||
}
|
||||
|
||||
if !sliceStringEqual(srv1.Arbiters, srv2.Arbiters) {
|
||||
return false
|
||||
}
|
||||
|
||||
if !sliceStringEqual(srv1.Hosts, srv2.Hosts) {
|
||||
return false
|
||||
}
|
||||
|
||||
if !sliceStringEqual(srv1.Passives, srv2.Passives) {
|
||||
return false
|
||||
}
|
||||
|
||||
if srv1.Primary != srv2.Primary {
|
||||
return false
|
||||
}
|
||||
|
||||
if srv1.SetName != srv2.SetName {
|
||||
return false
|
||||
}
|
||||
|
||||
if srv1.Kind != srv2.Kind {
|
||||
return false
|
||||
}
|
||||
|
||||
if srv1.LastError != nil || srv2.LastError != nil {
|
||||
if srv1.LastError == nil || srv2.LastError == nil {
|
||||
return false
|
||||
}
|
||||
if srv1.LastError.Error() != srv2.LastError.Error() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if !equalWireVersion(srv1.WireVersion, srv2.WireVersion) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(srv1.Tags) != len(srv2.Tags) || !srv1.Tags.ContainsAll(srv2.Tags) {
|
||||
return false
|
||||
}
|
||||
|
||||
if srv1.SetVersion != srv2.SetVersion {
|
||||
return false
|
||||
}
|
||||
|
||||
if srv1.ElectionID != srv2.ElectionID {
|
||||
return false
|
||||
}
|
||||
|
||||
if ptrutil.CompareInt64(srv1.SessionTimeoutMinutes, srv2.SessionTimeoutMinutes) != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
// If TopologyVersion is nil for both servers, CompareToIncoming will return -1 because it assumes that the
|
||||
// incoming response is newer. We want the descriptions to be considered equal in this case, though, so an
|
||||
// explicit check is required.
|
||||
if srv1.TopologyVersion == nil && srv2.TopologyVersion == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return CompareTopologyVersions(srv1.TopologyVersion, srv2.TopologyVersion) == 0
|
||||
}
|
||||
|
||||
// IsServerLoadBalanced checks if a description.Server describes a server that
|
||||
// is load balanced.
|
||||
func IsServerLoadBalanced(srv description.Server) bool {
|
||||
return srv.Kind == description.ServerKindLoadBalancer || srv.ServiceID != nil
|
||||
}
|
||||
|
||||
// stringSliceFromRawElement decodes the provided BSON element into a []string.
|
||||
// This internally calls StringSliceFromRawValue on the element's value. The
|
||||
// error conditions outlined in that function's documentation apply for this
|
||||
// function as well.
|
||||
func stringSliceFromRawElement(element bson.RawElement) ([]string, error) {
|
||||
return bsonutil.StringSliceFromRawValue(element.Key(), element.Value())
|
||||
}
|
||||
|
||||
func decodeStringMap(element bson.RawElement, name string) (map[string]string, error) {
|
||||
doc, ok := element.Value().DocumentOK()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected '%s' to be a document but it's a BSON %s", name, element.Value().Type)
|
||||
}
|
||||
elements, err := doc.Elements()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m := make(map[string]string)
|
||||
for _, element := range elements {
|
||||
key := element.Key()
|
||||
value, ok := element.Value().StringValueOK()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected '%s' to be a document of strings, but found a BSON %s", name, element.Value().Type)
|
||||
}
|
||||
m[key] = value
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// NewTopologyVersion creates a TopologyVersion based on doc
|
||||
func NewTopologyVersion(doc bson.Raw) (*description.TopologyVersion, error) {
|
||||
elements, err := doc.Elements()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var tv description.TopologyVersion
|
||||
var ok bool
|
||||
for _, element := range elements {
|
||||
switch element.Key() {
|
||||
case "processId":
|
||||
tv.ProcessID, ok = element.Value().ObjectIDOK()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected 'processId' to be a objectID but it's a BSON %s", element.Value().Type)
|
||||
}
|
||||
case "counter":
|
||||
tv.Counter, ok = element.Value().Int64OK()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected 'counter' to be an int64 but it's a BSON %s", element.Value().Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
return &tv, nil
|
||||
}
|
||||
|
||||
// NewVersionRange creates a new VersionRange given a min and a max.
|
||||
func NewVersionRange(min, max int32) description.VersionRange {
|
||||
return description.VersionRange{Min: min, Max: max}
|
||||
}
|
||||
|
||||
// VersionRangeIncludes returns a bool indicating whether the supplied integer
|
||||
// is included in the range.
|
||||
func VersionRangeIncludes(versionRange description.VersionRange, v int32) bool {
|
||||
return v >= versionRange.Min && v <= versionRange.Max
|
||||
}
|
||||
|
||||
// CompareTopologyVersions compares the receiver, which represents the currently
|
||||
// known TopologyVersion for a server, to an incoming TopologyVersion extracted
|
||||
// from a server command response.
|
||||
//
|
||||
// This returns -1 if the receiver version is less than the response, 0 if the
|
||||
// versions are equal, and 1 if the receiver version is greater than the
|
||||
// response. This comparison is not commutative.
|
||||
func CompareTopologyVersions(receiver, response *description.TopologyVersion) int {
|
||||
if receiver == nil || response == nil {
|
||||
return -1
|
||||
}
|
||||
if receiver.ProcessID != response.ProcessID {
|
||||
return -1
|
||||
}
|
||||
if receiver.Counter == response.Counter {
|
||||
return 0
|
||||
}
|
||||
if receiver.Counter < response.Counter {
|
||||
return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
// NewServerDescription creates a new server description from the given hello
|
||||
// command response.
|
||||
func NewServerDescription(addr address.Address, response bson.Raw) description.Server {
|
||||
desc := description.Server{Addr: addr, CanonicalAddr: addr, LastUpdateTime: time.Now().UTC()}
|
||||
elements, err := response.Elements()
|
||||
if err != nil {
|
||||
desc.LastError = err
|
||||
return desc
|
||||
}
|
||||
var ok bool
|
||||
var isReplicaSet, isWritablePrimary, hidden, secondary, arbiterOnly bool
|
||||
var msg string
|
||||
var versionRange description.VersionRange
|
||||
for _, element := range elements {
|
||||
switch element.Key() {
|
||||
case "arbiters":
|
||||
var err error
|
||||
desc.Arbiters, err = stringSliceFromRawElement(element)
|
||||
if err != nil {
|
||||
desc.LastError = err
|
||||
return desc
|
||||
}
|
||||
case "arbiterOnly":
|
||||
arbiterOnly, ok = element.Value().BooleanOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'arbiterOnly' to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "compression":
|
||||
var err error
|
||||
desc.Compression, err = stringSliceFromRawElement(element)
|
||||
if err != nil {
|
||||
desc.LastError = err
|
||||
return desc
|
||||
}
|
||||
case "electionId":
|
||||
desc.ElectionID, ok = element.Value().ObjectIDOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'electionId' to be a objectID but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "iscryptd":
|
||||
desc.IsCryptd, ok = element.Value().BooleanOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'iscryptd' to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "helloOk":
|
||||
desc.HelloOK, ok = element.Value().BooleanOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'helloOk' to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "hidden":
|
||||
hidden, ok = element.Value().BooleanOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'hidden' to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "hosts":
|
||||
var err error
|
||||
desc.Hosts, err = stringSliceFromRawElement(element)
|
||||
if err != nil {
|
||||
desc.LastError = err
|
||||
return desc
|
||||
}
|
||||
case "isWritablePrimary":
|
||||
isWritablePrimary, ok = element.Value().BooleanOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'isWritablePrimary' to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case handshake.LegacyHelloLowercase:
|
||||
isWritablePrimary, ok = element.Value().BooleanOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected legacy hello to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "isreplicaset":
|
||||
isReplicaSet, ok = element.Value().BooleanOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'isreplicaset' to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "lastWrite":
|
||||
lastWrite, ok := element.Value().DocumentOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'lastWrite' to be a document but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
dateTime, err := lastWrite.LookupErr("lastWriteDate")
|
||||
if err == nil {
|
||||
dt, ok := dateTime.DateTimeOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'lastWriteDate' to be a datetime but it's a BSON %s", dateTime.Type)
|
||||
return desc
|
||||
}
|
||||
desc.LastWriteTime = time.Unix(dt/1000, dt%1000*1000000).UTC()
|
||||
}
|
||||
case "logicalSessionTimeoutMinutes":
|
||||
i64, ok := element.Value().AsInt64OK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'logicalSessionTimeoutMinutes' to be an integer but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
|
||||
desc.SessionTimeoutMinutes = &i64
|
||||
case "maxBsonObjectSize":
|
||||
i64, ok := element.Value().AsInt64OK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'maxBsonObjectSize' to be an integer but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
desc.MaxDocumentSize = uint32(i64)
|
||||
case "maxMessageSizeBytes":
|
||||
i64, ok := element.Value().AsInt64OK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'maxMessageSizeBytes' to be an integer but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
desc.MaxMessageSize = uint32(i64)
|
||||
case "maxWriteBatchSize":
|
||||
i64, ok := element.Value().AsInt64OK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'maxWriteBatchSize' to be an integer but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
desc.MaxBatchCount = uint32(i64)
|
||||
case "me":
|
||||
me, ok := element.Value().StringValueOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'me' to be a string but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
desc.CanonicalAddr = address.Address(me).Canonicalize()
|
||||
case "maxWireVersion":
|
||||
verMax, ok := element.Value().AsInt64OK()
|
||||
versionRange.Max = int32(verMax)
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'maxWireVersion' to be an integer but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "minWireVersion":
|
||||
verMin, ok := element.Value().AsInt64OK()
|
||||
versionRange.Min = int32(verMin)
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'minWireVersion' to be an integer but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "msg":
|
||||
msg, ok = element.Value().StringValueOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'msg' to be a string but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "ok":
|
||||
okay, ok := element.Value().AsInt64OK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'ok' to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
if okay != 1 {
|
||||
desc.LastError = errors.New("not ok")
|
||||
return desc
|
||||
}
|
||||
case "passives":
|
||||
var err error
|
||||
desc.Passives, err = stringSliceFromRawElement(element)
|
||||
if err != nil {
|
||||
desc.LastError = err
|
||||
return desc
|
||||
}
|
||||
case "passive":
|
||||
desc.Passive, ok = element.Value().BooleanOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'passive' to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "primary":
|
||||
primary, ok := element.Value().StringValueOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'primary' to be a string but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
desc.Primary = address.Address(primary)
|
||||
case "readOnly":
|
||||
desc.ReadOnly, ok = element.Value().BooleanOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'readOnly' to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "secondary":
|
||||
secondary, ok = element.Value().BooleanOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'secondary' to be a boolean but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "serviceId":
|
||||
oid, ok := element.Value().ObjectIDOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'serviceId' to be an ObjectId but it's a BSON %s", element.Value().Type)
|
||||
}
|
||||
desc.ServiceID = &oid
|
||||
case "setName":
|
||||
desc.SetName, ok = element.Value().StringValueOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'setName' to be a string but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
case "setVersion":
|
||||
i64, ok := element.Value().AsInt64OK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'setVersion' to be an integer but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
desc.SetVersion = uint32(i64)
|
||||
case "tags":
|
||||
m, err := decodeStringMap(element, "tags")
|
||||
if err != nil {
|
||||
desc.LastError = err
|
||||
return desc
|
||||
}
|
||||
desc.Tags = tag.NewTagSetFromMap(m)
|
||||
case "topologyVersion":
|
||||
doc, ok := element.Value().DocumentOK()
|
||||
if !ok {
|
||||
desc.LastError = fmt.Errorf("expected 'topologyVersion' to be a document but it's a BSON %s", element.Value().Type)
|
||||
return desc
|
||||
}
|
||||
|
||||
desc.TopologyVersion, err = NewTopologyVersion(doc)
|
||||
if err != nil {
|
||||
desc.LastError = err
|
||||
return desc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, host := range desc.Hosts {
|
||||
desc.Members = append(desc.Members, address.Address(host).Canonicalize())
|
||||
}
|
||||
|
||||
for _, passive := range desc.Passives {
|
||||
desc.Members = append(desc.Members, address.Address(passive).Canonicalize())
|
||||
}
|
||||
|
||||
for _, arbiter := range desc.Arbiters {
|
||||
desc.Members = append(desc.Members, address.Address(arbiter).Canonicalize())
|
||||
}
|
||||
|
||||
desc.Kind = description.ServerKindStandalone
|
||||
|
||||
switch {
|
||||
case isReplicaSet:
|
||||
desc.Kind = description.ServerKindRSGhost
|
||||
case desc.SetName != "":
|
||||
switch {
|
||||
case isWritablePrimary:
|
||||
desc.Kind = description.ServerKindRSPrimary
|
||||
case hidden:
|
||||
desc.Kind = description.ServerKindRSMember
|
||||
case secondary:
|
||||
desc.Kind = description.ServerKindRSSecondary
|
||||
case arbiterOnly:
|
||||
desc.Kind = description.ServerKindRSArbiter
|
||||
default:
|
||||
desc.Kind = description.ServerKindRSMember
|
||||
}
|
||||
case msg == "isdbgrid":
|
||||
desc.Kind = description.ServerKindMongos
|
||||
}
|
||||
|
||||
desc.WireVersion = &versionRange
|
||||
|
||||
return desc
|
||||
}
|
||||
|
||||
func sliceStringEqual(a []string, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
128
server/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/hello.go
generated
vendored
Normal file
128
server/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/hello.go
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package driverutil
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const AwsLambdaPrefix = "AWS_Lambda_"
|
||||
|
||||
const (
|
||||
// FaaS environment variable names
|
||||
|
||||
// EnvVarAWSExecutionEnv is the AWS Execution environment variable.
|
||||
EnvVarAWSExecutionEnv = "AWS_EXECUTION_ENV"
|
||||
// EnvVarAWSLambdaRuntimeAPI is the AWS Lambda runtime API variable.
|
||||
EnvVarAWSLambdaRuntimeAPI = "AWS_LAMBDA_RUNTIME_API"
|
||||
// EnvVarFunctionsWorkerRuntime is the functions worker runtime variable.
|
||||
EnvVarFunctionsWorkerRuntime = "FUNCTIONS_WORKER_RUNTIME"
|
||||
// EnvVarKService is the K Service variable.
|
||||
EnvVarKService = "K_SERVICE"
|
||||
// EnvVarFunctionName is the function name variable.
|
||||
EnvVarFunctionName = "FUNCTION_NAME"
|
||||
// EnvVarVercel is the Vercel variable.
|
||||
EnvVarVercel = "VERCEL"
|
||||
// EnvVarK8s is the K8s variable.
|
||||
EnvVarK8s = "KUBERNETES_SERVICE_HOST"
|
||||
)
|
||||
|
||||
const (
|
||||
// FaaS environment variable names
|
||||
|
||||
// EnvVarAWSRegion is the AWS region variable.
|
||||
EnvVarAWSRegion = "AWS_REGION"
|
||||
// EnvVarAWSLambdaFunctionMemorySize is the AWS Lambda function memory size variable.
|
||||
EnvVarAWSLambdaFunctionMemorySize = "AWS_LAMBDA_FUNCTION_MEMORY_SIZE"
|
||||
// EnvVarFunctionMemoryMB is the function memory in megabytes variable.
|
||||
EnvVarFunctionMemoryMB = "FUNCTION_MEMORY_MB"
|
||||
// EnvVarFunctionTimeoutSec is the function timeout in seconds variable.
|
||||
EnvVarFunctionTimeoutSec = "FUNCTION_TIMEOUT_SEC"
|
||||
// EnvVarFunctionRegion is the function region variable.
|
||||
EnvVarFunctionRegion = "FUNCTION_REGION"
|
||||
// EnvVarVercelRegion is the Vercel region variable.
|
||||
EnvVarVercelRegion = "VERCEL_REGION"
|
||||
)
|
||||
|
||||
const (
|
||||
// FaaS environment names used by the client
|
||||
|
||||
// EnvNameAWSLambda is the AWS Lambda environment name.
|
||||
EnvNameAWSLambda = "aws.lambda"
|
||||
// EnvNameAzureFunc is the Azure Function environment name.
|
||||
EnvNameAzureFunc = "azure.func"
|
||||
// EnvNameGCPFunc is the Google Cloud Function environment name.
|
||||
EnvNameGCPFunc = "gcp.func"
|
||||
// EnvNameVercel is the Vercel environment name.
|
||||
EnvNameVercel = "vercel"
|
||||
)
|
||||
|
||||
// GetFaasEnvName parses the FaaS environment variable name and returns the
|
||||
// corresponding name used by the client. If none of the variables or variables
|
||||
// for multiple names are populated the client.env value MUST be entirely
|
||||
// omitted. When variables for multiple "client.env.name" values are present,
|
||||
// "vercel" takes precedence over "aws.lambda"; any other combination MUST cause
|
||||
// "client.env" to be entirely omitted.
|
||||
func GetFaasEnvName() string {
|
||||
envVars := []string{
|
||||
EnvVarAWSExecutionEnv,
|
||||
EnvVarAWSLambdaRuntimeAPI,
|
||||
EnvVarFunctionsWorkerRuntime,
|
||||
EnvVarKService,
|
||||
EnvVarFunctionName,
|
||||
EnvVarVercel,
|
||||
}
|
||||
|
||||
// If none of the variables are populated the client.env value MUST be
|
||||
// entirely omitted.
|
||||
names := make(map[string]struct{})
|
||||
|
||||
for _, envVar := range envVars {
|
||||
val := os.Getenv(envVar)
|
||||
if val == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
var name string
|
||||
|
||||
switch envVar {
|
||||
case EnvVarAWSExecutionEnv:
|
||||
if !strings.HasPrefix(val, AwsLambdaPrefix) {
|
||||
continue
|
||||
}
|
||||
|
||||
name = EnvNameAWSLambda
|
||||
case EnvVarAWSLambdaRuntimeAPI:
|
||||
name = EnvNameAWSLambda
|
||||
case EnvVarFunctionsWorkerRuntime:
|
||||
name = EnvNameAzureFunc
|
||||
case EnvVarKService, EnvVarFunctionName:
|
||||
name = EnvNameGCPFunc
|
||||
case EnvVarVercel:
|
||||
// "vercel" takes precedence over "aws.lambda".
|
||||
delete(names, EnvNameAWSLambda)
|
||||
|
||||
name = EnvNameVercel
|
||||
}
|
||||
|
||||
names[name] = struct{}{}
|
||||
if len(names) > 1 {
|
||||
// If multiple names are populated the client.env value
|
||||
// MUST be entirely omitted.
|
||||
names = nil
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for name := range names {
|
||||
return name
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
69
server/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/operation.go
generated
vendored
Normal file
69
server/vendor/go.mongodb.org/mongo-driver/v2/internal/driverutil/operation.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package driverutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Operation Names should be sourced from the command reference documentation:
|
||||
// https://www.mongodb.com/docs/manual/reference/command/
|
||||
const (
|
||||
AbortTransactionOp = "abortTransaction" // AbortTransactionOp is the name for aborting a transaction
|
||||
AggregateOp = "aggregate" // AggregateOp is the name for aggregating
|
||||
CommitTransactionOp = "commitTransaction" // CommitTransactionOp is the name for committing a transaction
|
||||
CountOp = "count" // CountOp is the name for counting
|
||||
CreateOp = "create" // CreateOp is the name for creating
|
||||
CreateIndexesOp = "createIndexes" // CreateIndexesOp is the name for creating indexes
|
||||
DeleteOp = "delete" // DeleteOp is the name for deleting
|
||||
DistinctOp = "distinct" // DistinctOp is the name for distinct
|
||||
DropOp = "drop" // DropOp is the name for dropping
|
||||
DropDatabaseOp = "dropDatabase" // DropDatabaseOp is the name for dropping a database
|
||||
DropIndexesOp = "dropIndexes" // DropIndexesOp is the name for dropping indexes
|
||||
EndSessionsOp = "endSessions" // EndSessionsOp is the name for ending sessions
|
||||
FindAndModifyOp = "findAndModify" // FindAndModifyOp is the name for finding and modifying
|
||||
FindOp = "find" // FindOp is the name for finding
|
||||
InsertOp = "insert" // InsertOp is the name for inserting
|
||||
ListCollectionsOp = "listCollections" // ListCollectionsOp is the name for listing collections
|
||||
ListIndexesOp = "listIndexes" // ListIndexesOp is the name for listing indexes
|
||||
ListDatabasesOp = "listDatabases" // ListDatabasesOp is the name for listing databases
|
||||
UpdateOp = "update" // UpdateOp is the name for updating
|
||||
BulkWriteOp = "bulkWrite" // BulkWriteOp is the name for client-level bulk write
|
||||
)
|
||||
|
||||
// CalculateMaxTimeMS calculates the maxTimeMS value to send to the server
|
||||
// based on the context deadline and the minimum round trip time. If the
|
||||
// calculated maxTimeMS is likely to cause a socket timeout, then this function
|
||||
// will return 0 and false.
|
||||
func CalculateMaxTimeMS(ctx context.Context, rttMin time.Duration) (int64, bool) {
|
||||
deadline, ok := ctx.Deadline()
|
||||
if !ok {
|
||||
return 0, true
|
||||
}
|
||||
|
||||
remainingTimeout := time.Until(deadline)
|
||||
|
||||
// Always round up to the next millisecond value so we never truncate the calculated
|
||||
// maxTimeMS value (e.g. 400 microseconds evaluates to 1ms, not 0ms).
|
||||
maxTimeMS := int64((remainingTimeout - rttMin + time.Millisecond - 1) / time.Millisecond)
|
||||
if maxTimeMS <= 0 {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// The server will return a "BadValue" error if maxTimeMS is greater
|
||||
// than the maximum positive int32 value (about 24.9 days). If the
|
||||
// user specified a timeout value greater than that, omit maxTimeMS
|
||||
// and let the client-side timeout handle cancelling the op if the
|
||||
// timeout is ever reached.
|
||||
if maxTimeMS > math.MaxInt32 {
|
||||
return 0, true
|
||||
}
|
||||
|
||||
return maxTimeMS, true
|
||||
}
|
||||
13
server/vendor/go.mongodb.org/mongo-driver/v2/internal/handshake/handshake.go
generated
vendored
Normal file
13
server/vendor/go.mongodb.org/mongo-driver/v2/internal/handshake/handshake.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package handshake
|
||||
|
||||
// LegacyHello is the legacy version of the hello command.
|
||||
var LegacyHello = "isMaster"
|
||||
|
||||
// LegacyHelloLowercase is the lowercase, legacy version of the hello command.
|
||||
var LegacyHelloLowercase = "ismaster"
|
||||
38
server/vendor/go.mongodb.org/mongo-driver/v2/internal/httputil/httputil.go
generated
vendored
Normal file
38
server/vendor/go.mongodb.org/mongo-driver/v2/internal/httputil/httputil.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) MongoDB, Inc. 2022-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package httputil
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var DefaultHTTPClient = &http.Client{}
|
||||
|
||||
// NewHTTPClient will return the globally-defined DefaultHTTPClient, updating
|
||||
// the transport if it differs from the http package DefaultTransport.
|
||||
func NewHTTPClient() *http.Client {
|
||||
client := DefaultHTTPClient
|
||||
if _, ok := http.DefaultTransport.(*http.Transport); !ok {
|
||||
client.Transport = http.DefaultTransport
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// CloseIdleHTTPConnections closes any connections which were previously
|
||||
// connected from previous requests but are now sitting idle in a "keep-alive"
|
||||
// state. It does not interrupt any connections currently in use.
|
||||
//
|
||||
// Borrowed from the Go standard library.
|
||||
func CloseIdleHTTPConnections(client *http.Client) {
|
||||
type closeIdler interface {
|
||||
CloseIdleConnections()
|
||||
}
|
||||
if tr, ok := client.Transport.(closeIdler); ok {
|
||||
tr.CloseIdleConnections()
|
||||
}
|
||||
}
|
||||
313
server/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/component.go
generated
vendored
Normal file
313
server/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/component.go
generated
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package logger
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
)
|
||||
|
||||
const (
|
||||
CommandFailed = "Command failed"
|
||||
CommandStarted = "Command started"
|
||||
CommandSucceeded = "Command succeeded"
|
||||
ConnectionPoolCreated = "Connection pool created"
|
||||
ConnectionPoolReady = "Connection pool ready"
|
||||
ConnectionPoolCleared = "Connection pool cleared"
|
||||
ConnectionPoolClosed = "Connection pool closed"
|
||||
ConnectionCreated = "Connection created"
|
||||
ConnectionReady = "Connection ready"
|
||||
ConnectionClosed = "Connection closed"
|
||||
ConnectionCheckoutStarted = "Connection checkout started"
|
||||
ConnectionCheckoutFailed = "Connection checkout failed"
|
||||
ConnectionCheckedOut = "Connection checked out"
|
||||
ConnectionCheckedIn = "Connection checked in"
|
||||
ServerSelectionFailed = "Server selection failed"
|
||||
ServerSelectionStarted = "Server selection started"
|
||||
ServerSelectionSucceeded = "Server selection succeeded"
|
||||
ServerSelectionWaiting = "Waiting for suitable server to become available"
|
||||
TopologyClosed = "Stopped topology monitoring"
|
||||
TopologyDescriptionChanged = "Topology description changed"
|
||||
TopologyOpening = "Starting topology monitoring"
|
||||
TopologyServerClosed = "Stopped server monitoring"
|
||||
TopologyServerHeartbeatFailed = "Server heartbeat failed"
|
||||
TopologyServerHeartbeatStarted = "Server heartbeat started"
|
||||
TopologyServerHeartbeatSucceeded = "Server heartbeat succeeded"
|
||||
TopologyServerOpening = "Starting server monitoring"
|
||||
)
|
||||
|
||||
const (
|
||||
KeyAwaited = "awaited"
|
||||
KeyCommand = "command"
|
||||
KeyCommandName = "commandName"
|
||||
KeyDatabaseName = "databaseName"
|
||||
KeyDriverConnectionID = "driverConnectionId"
|
||||
KeyDurationMS = "durationMS"
|
||||
KeyError = "error"
|
||||
KeyFailure = "failure"
|
||||
KeyMaxConnecting = "maxConnecting"
|
||||
KeyMaxIdleTimeMS = "maxIdleTimeMS"
|
||||
KeyMaxPoolSize = "maxPoolSize"
|
||||
KeyMessage = "message"
|
||||
KeyMinPoolSize = "minPoolSize"
|
||||
KeyNewDescription = "newDescription"
|
||||
KeyOperation = "operation"
|
||||
KeyOperationID = "operationId"
|
||||
KeyPreviousDescription = "previousDescription"
|
||||
KeyRemainingTimeMS = "remainingTimeMS"
|
||||
KeyReason = "reason"
|
||||
KeyReply = "reply"
|
||||
KeyRequestID = "requestId"
|
||||
KeySelector = "selector"
|
||||
KeyServerConnectionID = "serverConnectionId"
|
||||
KeyServerHost = "serverHost"
|
||||
KeyServerPort = "serverPort"
|
||||
KeyServiceID = "serviceId"
|
||||
KeyTimestamp = "timestamp"
|
||||
KeyTopologyDescription = "topologyDescription"
|
||||
KeyTopologyID = "topologyId"
|
||||
)
|
||||
|
||||
// KeyValues is a list of key-value pairs.
|
||||
type KeyValues []any
|
||||
|
||||
// Add adds a key-value pair to an instance of a KeyValues list.
|
||||
func (kvs *KeyValues) Add(key string, value any) {
|
||||
*kvs = append(*kvs, key, value)
|
||||
}
|
||||
|
||||
const (
|
||||
ReasonConnClosedStale = "Connection became stale because the pool was cleared"
|
||||
ReasonConnClosedIdle = "Connection has been available but unused for longer than the configured max idle time"
|
||||
ReasonConnClosedError = "An error occurred while using the connection"
|
||||
ReasonConnClosedPoolClosed = "Connection pool was closed"
|
||||
ReasonConnCheckoutFailedTimout = "Wait queue timeout elapsed without a connection becoming available"
|
||||
ReasonConnCheckoutFailedError = "An error occurred while trying to establish a new connection"
|
||||
ReasonConnCheckoutFailedPoolClosed = "Connection pool was closed"
|
||||
)
|
||||
|
||||
// Component is an enumeration representing the "components" which can be
|
||||
// logged against. A LogLevel can be configured on a per-component basis.
|
||||
type Component int
|
||||
|
||||
const (
|
||||
// ComponentAll enables logging for all components.
|
||||
ComponentAll Component = iota
|
||||
|
||||
// ComponentCommand enables command monitor logging.
|
||||
ComponentCommand
|
||||
|
||||
// ComponentTopology enables topology logging.
|
||||
ComponentTopology
|
||||
|
||||
// ComponentServerSelection enables server selection logging.
|
||||
ComponentServerSelection
|
||||
|
||||
// ComponentConnection enables connection services logging.
|
||||
ComponentConnection
|
||||
)
|
||||
|
||||
const (
|
||||
mongoDBLogAllEnvVar = "MONGODB_LOG_ALL"
|
||||
mongoDBLogCommandEnvVar = "MONGODB_LOG_COMMAND"
|
||||
mongoDBLogTopologyEnvVar = "MONGODB_LOG_TOPOLOGY"
|
||||
mongoDBLogServerSelectionEnvVar = "MONGODB_LOG_SERVER_SELECTION"
|
||||
mongoDBLogConnectionEnvVar = "MONGODB_LOG_CONNECTION"
|
||||
)
|
||||
|
||||
var componentEnvVarMap = map[string]Component{
|
||||
mongoDBLogAllEnvVar: ComponentAll,
|
||||
mongoDBLogCommandEnvVar: ComponentCommand,
|
||||
mongoDBLogTopologyEnvVar: ComponentTopology,
|
||||
mongoDBLogServerSelectionEnvVar: ComponentServerSelection,
|
||||
mongoDBLogConnectionEnvVar: ComponentConnection,
|
||||
}
|
||||
|
||||
// EnvHasComponentVariables returns true if the environment contains any of the
|
||||
// component environment variables.
|
||||
func EnvHasComponentVariables() bool {
|
||||
for envVar := range componentEnvVarMap {
|
||||
if os.Getenv(envVar) != "" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Command is a struct defining common fields that must be included in all
|
||||
// commands.
|
||||
type Command struct {
|
||||
DriverConnectionID int64 // Driver's ID for the connection
|
||||
Name string // Command name
|
||||
DatabaseName string // Database name
|
||||
Message string // Message associated with the command
|
||||
OperationID int32 // Driver-generated operation ID
|
||||
RequestID int64 // Driver-generated request ID
|
||||
ServerConnectionID *int64 // Server's ID for the connection used for the command
|
||||
ServerHost string // Hostname or IP address for the server
|
||||
ServerPort string // Port for the server
|
||||
ServiceID *bson.ObjectID // ID for the command in load balancer mode
|
||||
}
|
||||
|
||||
// SerializeCommand takes a command and a variable number of key-value pairs and
|
||||
// returns a slice of any that can be passed to the logger for
|
||||
// structured logging.
|
||||
func SerializeCommand(cmd Command, extraKeysAndValues ...any) KeyValues {
|
||||
// Initialize the boilerplate keys and values.
|
||||
keysAndValues := KeyValues{
|
||||
KeyCommandName, cmd.Name,
|
||||
KeyDatabaseName, cmd.DatabaseName,
|
||||
KeyDriverConnectionID, cmd.DriverConnectionID,
|
||||
KeyMessage, cmd.Message,
|
||||
KeyOperationID, cmd.OperationID,
|
||||
KeyRequestID, cmd.RequestID,
|
||||
KeyServerHost, cmd.ServerHost,
|
||||
}
|
||||
|
||||
// Add the extra keys and values.
|
||||
for i := 0; i < len(extraKeysAndValues); i += 2 {
|
||||
keysAndValues.Add(extraKeysAndValues[i].(string), extraKeysAndValues[i+1])
|
||||
}
|
||||
|
||||
port, err := strconv.ParseInt(cmd.ServerPort, 10, 32)
|
||||
if err == nil {
|
||||
keysAndValues.Add(KeyServerPort, port)
|
||||
}
|
||||
|
||||
// Add the "serverConnectionId" if it is not nil.
|
||||
if cmd.ServerConnectionID != nil {
|
||||
keysAndValues.Add(KeyServerConnectionID, *cmd.ServerConnectionID)
|
||||
}
|
||||
|
||||
// Add the "serviceId" if it is not nil.
|
||||
if cmd.ServiceID != nil {
|
||||
keysAndValues.Add(KeyServiceID, cmd.ServiceID.Hex())
|
||||
}
|
||||
|
||||
return keysAndValues
|
||||
}
|
||||
|
||||
// Connection contains data that all connection log messages MUST contain.
|
||||
type Connection struct {
|
||||
Message string // Message associated with the connection
|
||||
ServerHost string // Hostname or IP address for the server
|
||||
ServerPort string // Port for the server
|
||||
}
|
||||
|
||||
// SerializeConnection serializes a Connection message into a slice of keys and
|
||||
// values that can be passed to a logger.
|
||||
func SerializeConnection(conn Connection, extraKeysAndValues ...any) KeyValues {
|
||||
// Initialize the boilerplate keys and values.
|
||||
keysAndValues := KeyValues{
|
||||
KeyMessage, conn.Message,
|
||||
KeyServerHost, conn.ServerHost,
|
||||
}
|
||||
|
||||
// Add the optional keys and values.
|
||||
for i := 0; i < len(extraKeysAndValues); i += 2 {
|
||||
keysAndValues.Add(extraKeysAndValues[i].(string), extraKeysAndValues[i+1])
|
||||
}
|
||||
|
||||
port, err := strconv.ParseInt(conn.ServerPort, 10, 32)
|
||||
if err == nil {
|
||||
keysAndValues.Add(KeyServerPort, port)
|
||||
}
|
||||
|
||||
return keysAndValues
|
||||
}
|
||||
|
||||
// Server contains data that all server messages MAY contain.
|
||||
type Server struct {
|
||||
DriverConnectionID int64 // Driver's ID for the connection
|
||||
TopologyID bson.ObjectID // Driver's unique ID for this topology
|
||||
Message string // Message associated with the topology
|
||||
ServerConnectionID *int64 // Server's ID for the connection
|
||||
ServerHost string // Hostname or IP address for the server
|
||||
ServerPort string // Port for the server
|
||||
}
|
||||
|
||||
// SerializeServer serializes a Server message into a slice of keys and
|
||||
// values that can be passed to a logger.
|
||||
func SerializeServer(srv Server, extraKV ...any) KeyValues {
|
||||
// Initialize the boilerplate keys and values.
|
||||
keysAndValues := KeyValues{
|
||||
KeyDriverConnectionID, srv.DriverConnectionID,
|
||||
KeyMessage, srv.Message,
|
||||
KeyServerHost, srv.ServerHost,
|
||||
KeyTopologyID, srv.TopologyID.Hex(),
|
||||
}
|
||||
|
||||
if connID := srv.ServerConnectionID; connID != nil {
|
||||
keysAndValues.Add(KeyServerConnectionID, *connID)
|
||||
}
|
||||
|
||||
port, err := strconv.ParseInt(srv.ServerPort, 10, 32)
|
||||
if err == nil {
|
||||
keysAndValues.Add(KeyServerPort, port)
|
||||
}
|
||||
|
||||
// Add the optional keys and values.
|
||||
for i := 0; i < len(extraKV); i += 2 {
|
||||
keysAndValues.Add(extraKV[i].(string), extraKV[i+1])
|
||||
}
|
||||
|
||||
return keysAndValues
|
||||
}
|
||||
|
||||
// ServerSelection contains data that all server selection messages MUST
|
||||
// contain.
|
||||
type ServerSelection struct {
|
||||
Selector string
|
||||
OperationID *int32
|
||||
Operation string
|
||||
TopologyDescription string
|
||||
}
|
||||
|
||||
// SerializeServerSelection serializes a Topology message into a slice of keys
|
||||
// and values that can be passed to a logger.
|
||||
func SerializeServerSelection(srvSelection ServerSelection, extraKV ...any) KeyValues {
|
||||
keysAndValues := KeyValues{
|
||||
KeySelector, srvSelection.Selector,
|
||||
KeyOperation, srvSelection.Operation,
|
||||
KeyTopologyDescription, srvSelection.TopologyDescription,
|
||||
}
|
||||
|
||||
if srvSelection.OperationID != nil {
|
||||
keysAndValues.Add(KeyOperationID, *srvSelection.OperationID)
|
||||
}
|
||||
|
||||
// Add the optional keys and values.
|
||||
for i := 0; i < len(extraKV); i += 2 {
|
||||
keysAndValues.Add(extraKV[i].(string), extraKV[i+1])
|
||||
}
|
||||
|
||||
return keysAndValues
|
||||
}
|
||||
|
||||
// Topology contains data that all topology messages MAY contain.
|
||||
type Topology struct {
|
||||
ID bson.ObjectID // Driver's unique ID for this topology
|
||||
Message string // Message associated with the topology
|
||||
}
|
||||
|
||||
// SerializeTopology serializes a Topology message into a slice of keys and
|
||||
// values that can be passed to a logger.
|
||||
func SerializeTopology(topo Topology, extraKV ...any) KeyValues {
|
||||
keysAndValues := KeyValues{
|
||||
KeyTopologyID, topo.ID.Hex(),
|
||||
}
|
||||
|
||||
// Add the optional keys and values.
|
||||
for i := 0; i < len(extraKV); i += 2 {
|
||||
keysAndValues.Add(extraKV[i].(string), extraKV[i+1])
|
||||
}
|
||||
|
||||
return keysAndValues
|
||||
}
|
||||
48
server/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/context.go
generated
vendored
Normal file
48
server/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/context.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package logger
|
||||
|
||||
import "context"
|
||||
|
||||
// contextKey is a custom type used to prevent key collisions when using the
|
||||
// context package.
|
||||
type contextKey string
|
||||
|
||||
const (
|
||||
contextKeyOperation contextKey = "operation"
|
||||
contextKeyOperationID contextKey = "operationID"
|
||||
)
|
||||
|
||||
// WithOperationName adds the operation name to the context.
|
||||
func WithOperationName(ctx context.Context, operation string) context.Context {
|
||||
return context.WithValue(ctx, contextKeyOperation, operation)
|
||||
}
|
||||
|
||||
// WithOperationID adds the operation ID to the context.
|
||||
func WithOperationID(ctx context.Context, operationID int32) context.Context {
|
||||
return context.WithValue(ctx, contextKeyOperationID, operationID)
|
||||
}
|
||||
|
||||
// OperationName returns the operation name from the context.
|
||||
func OperationName(ctx context.Context) (string, bool) {
|
||||
operationName := ctx.Value(contextKeyOperation)
|
||||
if operationName == nil {
|
||||
return "", false
|
||||
}
|
||||
|
||||
return operationName.(string), true
|
||||
}
|
||||
|
||||
// OperationID returns the operation ID from the context.
|
||||
func OperationID(ctx context.Context) (int32, bool) {
|
||||
operationID := ctx.Value(contextKeyOperationID)
|
||||
if operationID == nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return operationID.(int32), true
|
||||
}
|
||||
63
server/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/io_sink.go
generated
vendored
Normal file
63
server/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/io_sink.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package logger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"math"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// IOSink writes a JSON-encoded message to the io.Writer.
|
||||
type IOSink struct {
|
||||
enc *json.Encoder
|
||||
|
||||
// encMu protects the encoder from concurrent writes. While the logger
|
||||
// itself does not concurrently write to the sink, the sink may be used
|
||||
// concurrently within the driver.
|
||||
encMu sync.Mutex
|
||||
}
|
||||
|
||||
// Compile-time check to ensure IOSink implements the LogSink interface.
|
||||
var _ LogSink = &IOSink{}
|
||||
|
||||
// NewIOSink will create an IOSink object that writes JSON messages to the
|
||||
// provided io.Writer.
|
||||
func NewIOSink(out io.Writer) *IOSink {
|
||||
return &IOSink{
|
||||
enc: json.NewEncoder(out),
|
||||
}
|
||||
}
|
||||
|
||||
// Info will write a JSON-encoded message to the io.Writer.
|
||||
func (sink *IOSink) Info(_ int, msg string, keysAndValues ...any) {
|
||||
mapSize := len(keysAndValues) / 2
|
||||
if math.MaxInt-mapSize >= 2 {
|
||||
mapSize += 2
|
||||
}
|
||||
kvMap := make(map[string]any, mapSize)
|
||||
|
||||
kvMap[KeyTimestamp] = time.Now().UnixNano()
|
||||
kvMap[KeyMessage] = msg
|
||||
|
||||
for i := 0; i < len(keysAndValues); i += 2 {
|
||||
kvMap[keysAndValues[i].(string)] = keysAndValues[i+1]
|
||||
}
|
||||
|
||||
sink.encMu.Lock()
|
||||
defer sink.encMu.Unlock()
|
||||
|
||||
_ = sink.enc.Encode(kvMap)
|
||||
}
|
||||
|
||||
// Error will write a JSON-encoded error message to the io.Writer.
|
||||
func (sink *IOSink) Error(err error, msg string, kv ...any) {
|
||||
kv = append(kv, KeyError, err.Error())
|
||||
sink.Info(0, msg, kv...)
|
||||
}
|
||||
74
server/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/level.go
generated
vendored
Normal file
74
server/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/level.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package logger
|
||||
|
||||
import "strings"
|
||||
|
||||
// DiffToInfo is the number of levels in the Go Driver that come before the
|
||||
// "Info" level. This should ensure that "Info" is the 0th level passed to the
|
||||
// sink.
|
||||
const DiffToInfo = 1
|
||||
|
||||
// Level is an enumeration representing the log severity levels supported by
|
||||
// the driver. The order of the logging levels is important. The driver expects
|
||||
// that a user will likely use the "logr" package to create a LogSink, which
|
||||
// defaults InfoLevel as 0. Any additions to the Level enumeration before the
|
||||
// InfoLevel will need to also update the "diffToInfo" constant.
|
||||
type Level int
|
||||
|
||||
const (
|
||||
// LevelOff suppresses logging.
|
||||
LevelOff Level = iota
|
||||
|
||||
// LevelInfo enables logging of informational messages. These logs are
|
||||
// high-level information about normal driver behavior.
|
||||
LevelInfo
|
||||
|
||||
// LevelDebug enables logging of debug messages. These logs can be
|
||||
// voluminous and are intended for detailed information that may be
|
||||
// helpful when debugging an application.
|
||||
LevelDebug
|
||||
)
|
||||
|
||||
const (
|
||||
levelLiteralOff = "off"
|
||||
levelLiteralEmergency = "emergency"
|
||||
levelLiteralAlert = "alert"
|
||||
levelLiteralCritical = "critical"
|
||||
levelLiteralError = "error"
|
||||
levelLiteralWarning = "warning"
|
||||
levelLiteralNotice = "notice"
|
||||
levelLiteralInfo = "info"
|
||||
levelLiteralDebug = "debug"
|
||||
levelLiteralTrace = "trace"
|
||||
)
|
||||
|
||||
var LevelLiteralMap = map[string]Level{
|
||||
levelLiteralOff: LevelOff,
|
||||
levelLiteralEmergency: LevelInfo,
|
||||
levelLiteralAlert: LevelInfo,
|
||||
levelLiteralCritical: LevelInfo,
|
||||
levelLiteralError: LevelInfo,
|
||||
levelLiteralWarning: LevelInfo,
|
||||
levelLiteralNotice: LevelInfo,
|
||||
levelLiteralInfo: LevelInfo,
|
||||
levelLiteralDebug: LevelDebug,
|
||||
levelLiteralTrace: LevelDebug,
|
||||
}
|
||||
|
||||
// ParseLevel will check if the given string is a valid environment variable
|
||||
// for a logging severity level. If it is, then it will return the associated
|
||||
// driver's Level. The default Level is “LevelOff”.
|
||||
func ParseLevel(str string) Level {
|
||||
for literal, level := range LevelLiteralMap {
|
||||
if strings.EqualFold(literal, str) {
|
||||
return level
|
||||
}
|
||||
}
|
||||
|
||||
return LevelOff
|
||||
}
|
||||
266
server/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/logger.go
generated
vendored
Normal file
266
server/vendor/go.mongodb.org/mongo-driver/v2/internal/logger/logger.go
generated
vendored
Normal file
@@ -0,0 +1,266 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Package logger provides the internal logging solution for the MongoDB Go
|
||||
// Driver.
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
"go.mongodb.org/mongo-driver/v2/internal/bsoncoreutil"
|
||||
"go.mongodb.org/mongo-driver/v2/x/bsonx/bsoncore"
|
||||
)
|
||||
|
||||
// DefaultMaxDocumentLength is the default maximum number of bytes that can be
|
||||
// logged for a stringified BSON document.
|
||||
const DefaultMaxDocumentLength = 1000
|
||||
|
||||
// TruncationSuffix are trailing ellipsis "..." appended to a message to
|
||||
// indicate to the user that truncation occurred. This constant does not count
|
||||
// toward the max document length.
|
||||
const TruncationSuffix = "..."
|
||||
|
||||
const (
|
||||
logSinkPathEnvVar = "MONGODB_LOG_PATH"
|
||||
maxDocumentLengthEnvVar = "MONGODB_LOG_MAX_DOCUMENT_LENGTH"
|
||||
)
|
||||
|
||||
// LogSink represents a logging implementation, this interface should be 1-1
|
||||
// with the exported "LogSink" interface in the mongo/options package.
|
||||
type LogSink interface {
|
||||
// Info logs a non-error message with the given key/value pairs. The
|
||||
// level argument is provided for optional logging.
|
||||
Info(level int, msg string, keysAndValues ...any)
|
||||
|
||||
// Error logs an error, with the given message and key/value pairs.
|
||||
Error(err error, msg string, keysAndValues ...any)
|
||||
}
|
||||
|
||||
// Logger represents the configuration for the internal logger.
|
||||
type Logger struct {
|
||||
ComponentLevels map[Component]Level // Log levels for each component.
|
||||
Sink LogSink // LogSink for log printing.
|
||||
MaxDocumentLength uint // Command truncation width.
|
||||
logFile *os.File // File to write logs to.
|
||||
}
|
||||
|
||||
// New will construct a new logger. If any of the given options are the
|
||||
// zero-value of the argument type, then the constructor will attempt to
|
||||
// source the data from the environment. If the environment has not been set,
|
||||
// then the constructor will the respective default values.
|
||||
func New(sink LogSink, maxDocLen uint, compLevels map[Component]Level) (*Logger, error) {
|
||||
logger := &Logger{
|
||||
ComponentLevels: selectComponentLevels(compLevels),
|
||||
MaxDocumentLength: selectMaxDocumentLength(maxDocLen),
|
||||
}
|
||||
|
||||
sink, logFile, err := selectLogSink(sink)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logger.Sink = sink
|
||||
logger.logFile = logFile
|
||||
|
||||
return logger, nil
|
||||
}
|
||||
|
||||
// Close will close the logger's log file, if it exists.
|
||||
func (logger *Logger) Close() error {
|
||||
if logger.logFile != nil {
|
||||
return logger.logFile.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LevelComponentEnabled will return true if the given LogLevel is enabled for
|
||||
// the given LogComponent. If the ComponentLevels on the logger are enabled for
|
||||
// "ComponentAll", then this function will return true for any level bound by
|
||||
// the level assigned to "ComponentAll".
|
||||
//
|
||||
// If the level is not enabled (i.e. LevelOff), then false is returned. This is
|
||||
// to avoid false positives, such as returning "true" for a component that is
|
||||
// not enabled. For example, without this condition, an empty LevelComponent
|
||||
// would be considered "enabled" for "LevelOff".
|
||||
func (logger *Logger) LevelComponentEnabled(level Level, component Component) bool {
|
||||
if level == LevelOff {
|
||||
return false
|
||||
}
|
||||
|
||||
if logger.ComponentLevels == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return logger.ComponentLevels[component] >= level ||
|
||||
logger.ComponentLevels[ComponentAll] >= level
|
||||
}
|
||||
|
||||
// Print will synchronously print the given message to the configured LogSink.
|
||||
// If the LogSink is nil, then this method will do nothing. Future work could be done to make
|
||||
// this method asynchronous, see buffer management in libraries such as log4j.
|
||||
//
|
||||
// It's worth noting that many structured logs defined by DBX-wide
|
||||
// specifications include a "message" field, which is often shared with the
|
||||
// message arguments passed to this print function. The "Info" method used by
|
||||
// this function is implemented based on the go-logr/logr LogSink interface,
|
||||
// which is why "Print" has a message parameter. Any duplication in code is
|
||||
// intentional to adhere to the logr pattern.
|
||||
func (logger *Logger) Print(level Level, component Component, msg string, keysAndValues ...any) {
|
||||
// If the level is not enabled for the component, then
|
||||
// skip the message.
|
||||
if !logger.LevelComponentEnabled(level, component) {
|
||||
return
|
||||
}
|
||||
|
||||
// If the sink is nil, then skip the message.
|
||||
if logger.Sink == nil {
|
||||
return
|
||||
}
|
||||
|
||||
logger.Sink.Info(int(level)-DiffToInfo, msg, keysAndValues...)
|
||||
}
|
||||
|
||||
// Error logs an error, with the given message and key/value pairs.
|
||||
// It functions similarly to Print, but may have unique behavior, and should be
|
||||
// preferred for logging errors.
|
||||
func (logger *Logger) Error(err error, msg string, keysAndValues ...any) {
|
||||
if logger.Sink == nil {
|
||||
return
|
||||
}
|
||||
|
||||
logger.Sink.Error(err, msg, keysAndValues...)
|
||||
}
|
||||
|
||||
// selectMaxDocumentLength will return the integer value of the first non-zero
|
||||
// function, with the user-defined function taking priority over the environment
|
||||
// variables. For the environment, the function will attempt to get the value of
|
||||
// "MONGODB_LOG_MAX_DOCUMENT_LENGTH" and parse it as an unsigned integer. If the
|
||||
// environment variable is not set or is not an unsigned integer, then this
|
||||
// function will return the default max document length.
|
||||
func selectMaxDocumentLength(maxDocLen uint) uint {
|
||||
if maxDocLen != 0 {
|
||||
return maxDocLen
|
||||
}
|
||||
|
||||
maxDocLenEnv := os.Getenv(maxDocumentLengthEnvVar)
|
||||
if maxDocLenEnv != "" {
|
||||
maxDocLenEnvInt, err := strconv.ParseUint(maxDocLenEnv, 10, 32)
|
||||
if err == nil {
|
||||
return uint(maxDocLenEnvInt)
|
||||
}
|
||||
}
|
||||
|
||||
return DefaultMaxDocumentLength
|
||||
}
|
||||
|
||||
const (
|
||||
logSinkPathStdout = "stdout"
|
||||
logSinkPathStderr = "stderr"
|
||||
)
|
||||
|
||||
// selectLogSink will return the first non-nil LogSink, with the user-defined
|
||||
// LogSink taking precedence over the environment-defined LogSink. If no LogSink
|
||||
// is defined, then this function will return a LogSink that writes to stderr.
|
||||
func selectLogSink(sink LogSink) (LogSink, *os.File, error) {
|
||||
if sink != nil {
|
||||
return sink, nil, nil
|
||||
}
|
||||
|
||||
path := os.Getenv(logSinkPathEnvVar)
|
||||
lowerPath := strings.ToLower(path)
|
||||
|
||||
if lowerPath == string(logSinkPathStderr) {
|
||||
return NewIOSink(os.Stderr), nil, nil
|
||||
}
|
||||
|
||||
if lowerPath == string(logSinkPathStdout) {
|
||||
return NewIOSink(os.Stdout), nil, nil
|
||||
}
|
||||
|
||||
if path != "" {
|
||||
logFile, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0o666)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to open log file: %w", err)
|
||||
}
|
||||
|
||||
return NewIOSink(logFile), logFile, nil
|
||||
}
|
||||
|
||||
return NewIOSink(os.Stderr), nil, nil
|
||||
}
|
||||
|
||||
// selectComponentLevels returns a new map of LogComponents to LogLevels that is
|
||||
// the result of merging the user-defined data with the environment, with the
|
||||
// user-defined data taking priority.
|
||||
func selectComponentLevels(componentLevels map[Component]Level) map[Component]Level {
|
||||
selected := make(map[Component]Level)
|
||||
|
||||
// Determine if the "MONGODB_LOG_ALL" environment variable is set.
|
||||
var globalEnvLevel *Level
|
||||
if all := os.Getenv(mongoDBLogAllEnvVar); all != "" {
|
||||
level := ParseLevel(all)
|
||||
globalEnvLevel = &level
|
||||
}
|
||||
|
||||
for envVar, component := range componentEnvVarMap {
|
||||
// If the component already has a level, then skip it.
|
||||
if _, ok := componentLevels[component]; ok {
|
||||
selected[component] = componentLevels[component]
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// If the "MONGODB_LOG_ALL" environment variable is set, then
|
||||
// set the level for the component to the value of the
|
||||
// environment variable.
|
||||
if globalEnvLevel != nil {
|
||||
selected[component] = *globalEnvLevel
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// Otherwise, set the level for the component to the value of
|
||||
// the environment variable.
|
||||
selected[component] = ParseLevel(os.Getenv(envVar))
|
||||
}
|
||||
|
||||
return selected
|
||||
}
|
||||
|
||||
// FormatDocument formats a BSON document or RawValue for logging. The document is truncated
|
||||
// to the given width.
|
||||
func FormatDocument(msg bson.Raw, width uint) string {
|
||||
if len(msg) == 0 {
|
||||
return "{}"
|
||||
}
|
||||
|
||||
str, truncated := bsoncore.Document(msg).StringN(int(width))
|
||||
|
||||
if truncated {
|
||||
str += TruncationSuffix
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// FormatString formats a String for logging. The string is truncated
|
||||
// to the given width.
|
||||
func FormatString(str string, width uint) string {
|
||||
strTrunc := bsoncoreutil.Truncate(str, int(width))
|
||||
|
||||
// Checks if the string was truncating by comparing the lengths of the two strings.
|
||||
if len(strTrunc) < len(str) {
|
||||
strTrunc += TruncationSuffix
|
||||
}
|
||||
|
||||
return strTrunc
|
||||
}
|
||||
101
server/vendor/go.mongodb.org/mongo-driver/v2/internal/mongoutil/mongoutil.go
generated
vendored
Normal file
101
server/vendor/go.mongodb.org/mongo-driver/v2/internal/mongoutil/mongoutil.go
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright (C) MongoDB, Inc. 2024-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package mongoutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
||||
)
|
||||
|
||||
// NewOptions will functionally merge a slice of mongo.Options in a
|
||||
// "last-one-wins" manner, where nil options are ignored.
|
||||
func NewOptions[T any](opts ...options.Lister[T]) (*T, error) {
|
||||
args := new(T)
|
||||
for _, opt := range opts {
|
||||
if opt == nil || reflect.ValueOf(opt).IsNil() {
|
||||
// Do nothing if the option is nil or if opt is nil but implicitly cast as
|
||||
// an Options interface by the NewArgsFromOptions function. The latter
|
||||
// case would look something like this:
|
||||
continue
|
||||
}
|
||||
|
||||
for _, setArgs := range opt.List() {
|
||||
if setArgs == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := setArgs(args); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// OptionsLister implements an options.SetterLister object for an arbitrary
|
||||
// options type.
|
||||
type OptionsLister[T any] struct {
|
||||
Options *T // Arguments to set on the option type
|
||||
Callback func(*T) error // A callback for further modification
|
||||
}
|
||||
|
||||
// List will re-assign the entire argument option to the Args field
|
||||
// defined on opts. If a callback exists, that function will be executed to
|
||||
// further modify the arguments.
|
||||
func (opts *OptionsLister[T]) List() []func(*T) error {
|
||||
return []func(*T) error{
|
||||
func(args *T) error {
|
||||
if opts.Options != nil {
|
||||
*args = *opts.Options
|
||||
}
|
||||
|
||||
if opts.Callback != nil {
|
||||
return opts.Callback(args)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewOptionsLister will construct a SetterLister from the provided Options
|
||||
// object.
|
||||
func NewOptionsLister[T any](args *T, callback func(*T) error) *OptionsLister[T] {
|
||||
return &OptionsLister[T]{Options: args, Callback: callback}
|
||||
}
|
||||
|
||||
// AuthFromURI will create a Credentials object given the provided URI.
|
||||
func AuthFromURI(uri string) (*options.Credential, error) {
|
||||
opts := options.Client().ApplyURI(uri)
|
||||
|
||||
return opts.Auth, nil
|
||||
}
|
||||
|
||||
// HostsFromURI will parse the hosts in the URI and return them as a slice of
|
||||
// strings.
|
||||
func HostsFromURI(uri string) ([]string, error) {
|
||||
opts := options.Client().ApplyURI(uri)
|
||||
|
||||
return opts.Hosts, nil
|
||||
}
|
||||
|
||||
// TimeoutWithinContext will return true if the provided timeout is nil or if
|
||||
// it is less than the context deadline. If the context does not have a
|
||||
// deadline, it will return true.
|
||||
func TimeoutWithinContext(ctx context.Context, timeout time.Duration) bool {
|
||||
deadline, ok := ctx.Deadline()
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
|
||||
ctxTimeout := time.Until(deadline)
|
||||
|
||||
return ctxTimeout <= 0 || timeout < ctxTimeout
|
||||
}
|
||||
45
server/vendor/go.mongodb.org/mongo-driver/v2/internal/optionsutil/options.go
generated
vendored
Normal file
45
server/vendor/go.mongodb.org/mongo-driver/v2/internal/optionsutil/options.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (C) MongoDB, Inc. 2025-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package optionsutil
|
||||
|
||||
// Options stores internal options.
|
||||
type Options struct {
|
||||
values map[string]any
|
||||
}
|
||||
|
||||
// WithValue sets an option value with the associated key.
|
||||
func WithValue(opts Options, key string, option any) Options {
|
||||
if opts.values == nil {
|
||||
opts.values = make(map[string]any)
|
||||
}
|
||||
opts.values[key] = option
|
||||
return opts
|
||||
}
|
||||
|
||||
// Value returns the value associated with the options for key.
|
||||
func Value(opts Options, key string) any {
|
||||
if opts.values == nil {
|
||||
return nil
|
||||
}
|
||||
if val, ok := opts.values[key]; ok {
|
||||
return val
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Equal compares two Options instances for equality.
|
||||
func Equal(opts1, opts2 Options) bool {
|
||||
if len(opts1.values) != len(opts2.values) {
|
||||
return false
|
||||
}
|
||||
for key, val1 := range opts1.values {
|
||||
if val2, ok := opts2.values[key]; !ok || val1 != val2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
39
server/vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/int64.go
generated
vendored
Normal file
39
server/vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/int64.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) MongoDB, Inc. 2023-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package ptrutil
|
||||
|
||||
// CompareInt64 is a piecewise function with the following return conditions:
|
||||
//
|
||||
// (1) 2, ptr1 != nil AND ptr2 == nil
|
||||
// (2) 1, *ptr1 > *ptr2
|
||||
// (3) 0, ptr1 == ptr2 or *ptr1 == *ptr2
|
||||
// (4) -1, *ptr1 < *ptr2
|
||||
// (5) -2, ptr1 == nil AND ptr2 != nil
|
||||
func CompareInt64(ptr1, ptr2 *int64) int {
|
||||
if ptr1 == ptr2 {
|
||||
// This will catch the double nil or same-pointer cases.
|
||||
return 0
|
||||
}
|
||||
|
||||
if ptr1 == nil && ptr2 != nil {
|
||||
return -2
|
||||
}
|
||||
|
||||
if ptr1 != nil && ptr2 == nil {
|
||||
return 2
|
||||
}
|
||||
|
||||
if *ptr1 > *ptr2 {
|
||||
return 1
|
||||
}
|
||||
|
||||
if *ptr1 < *ptr2 {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
12
server/vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/ptr.go
generated
vendored
Normal file
12
server/vendor/go.mongodb.org/mongo-driver/v2/internal/ptrutil/ptr.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (C) MongoDB, Inc. 2024-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package ptrutil
|
||||
|
||||
// Ptr will return the memory location of the given value.
|
||||
func Ptr[T any](val T) *T {
|
||||
return &val
|
||||
}
|
||||
38
server/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/bits.go
generated
vendored
Normal file
38
server/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/bits.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copied from https://cs.opensource.google/go/go/+/946b4baaf6521d521928500b2b57429c149854e7:src/math/bits.go
|
||||
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rand
|
||||
|
||||
// Add64 returns the sum with carry of x, y and carry: sum = x + y + carry.
|
||||
// The carry input must be 0 or 1; otherwise the behavior is undefined.
|
||||
// The carryOut output is guaranteed to be 0 or 1.
|
||||
func Add64(x, y, carry uint64) (sum, carryOut uint64) {
|
||||
yc := y + carry
|
||||
sum = x + yc
|
||||
if sum < x || yc < y {
|
||||
carryOut = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Mul64 returns the 128-bit product of x and y: (hi, lo) = x * y
|
||||
// with the product bits' upper half returned in hi and the lower
|
||||
// half returned in lo.
|
||||
func Mul64(x, y uint64) (hi, lo uint64) {
|
||||
const mask32 = 1<<32 - 1
|
||||
x0 := x & mask32
|
||||
x1 := x >> 32
|
||||
y0 := y & mask32
|
||||
y1 := y >> 32
|
||||
w0 := x0 * y0
|
||||
t := x1*y0 + w0>>32
|
||||
w1 := t & mask32
|
||||
w2 := t >> 32
|
||||
w1 += x0 * y1
|
||||
hi = x1*y1 + w2 + w1>>32
|
||||
lo = x * y
|
||||
return
|
||||
}
|
||||
225
server/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/exp.go
generated
vendored
Normal file
225
server/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/exp.go
generated
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
// Copied from https://cs.opensource.google/go/x/exp/+/24438e51023af3bfc1db8aed43c1342817e8cfcd:rand/exp.go
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rand
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
* Exponential distribution
|
||||
*
|
||||
* See "The Ziggurat Method for Generating Random Variables"
|
||||
* (Marsaglia & Tsang, 2000)
|
||||
* http://www.jstatsoft.org/v05/i08/paper [pdf]
|
||||
*/
|
||||
|
||||
const (
|
||||
re = 7.69711747013104972
|
||||
)
|
||||
|
||||
// ExpFloat64 returns an exponentially distributed float64 in the range
|
||||
// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
|
||||
// (lambda) is 1 and whose mean is 1/lambda (1).
|
||||
// To produce a distribution with a different rate parameter,
|
||||
// callers can adjust the output using:
|
||||
//
|
||||
// sample = ExpFloat64() / desiredRateParameter
|
||||
func (r *Rand) ExpFloat64() float64 {
|
||||
for {
|
||||
j := r.Uint32()
|
||||
i := j & 0xFF
|
||||
x := float64(j) * float64(we[i])
|
||||
if j < ke[i] {
|
||||
return x
|
||||
}
|
||||
if i == 0 {
|
||||
return re - math.Log(r.Float64())
|
||||
}
|
||||
if fe[i]+float32(r.Float64())*(fe[i-1]-fe[i]) < float32(math.Exp(-x)) {
|
||||
return x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ke = [256]uint32{
|
||||
0xe290a139, 0x0, 0x9beadebc, 0xc377ac71, 0xd4ddb990,
|
||||
0xde893fb8, 0xe4a8e87c, 0xe8dff16a, 0xebf2deab, 0xee49a6e8,
|
||||
0xf0204efd, 0xf19bdb8e, 0xf2d458bb, 0xf3da104b, 0xf4b86d78,
|
||||
0xf577ad8a, 0xf61de83d, 0xf6afb784, 0xf730a573, 0xf7a37651,
|
||||
0xf80a5bb6, 0xf867189d, 0xf8bb1b4f, 0xf9079062, 0xf94d70ca,
|
||||
0xf98d8c7d, 0xf9c8928a, 0xf9ff175b, 0xfa319996, 0xfa6085f8,
|
||||
0xfa8c3a62, 0xfab5084e, 0xfadb36c8, 0xfaff0410, 0xfb20a6ea,
|
||||
0xfb404fb4, 0xfb5e2951, 0xfb7a59e9, 0xfb95038c, 0xfbae44ba,
|
||||
0xfbc638d8, 0xfbdcf892, 0xfbf29a30, 0xfc0731df, 0xfc1ad1ed,
|
||||
0xfc2d8b02, 0xfc3f6c4d, 0xfc5083ac, 0xfc60ddd1, 0xfc708662,
|
||||
0xfc7f8810, 0xfc8decb4, 0xfc9bbd62, 0xfca9027c, 0xfcb5c3c3,
|
||||
0xfcc20864, 0xfccdd70a, 0xfcd935e3, 0xfce42ab0, 0xfceebace,
|
||||
0xfcf8eb3b, 0xfd02c0a0, 0xfd0c3f59, 0xfd156b7b, 0xfd1e48d6,
|
||||
0xfd26daff, 0xfd2f2552, 0xfd372af7, 0xfd3eeee5, 0xfd4673e7,
|
||||
0xfd4dbc9e, 0xfd54cb85, 0xfd5ba2f2, 0xfd62451b, 0xfd68b415,
|
||||
0xfd6ef1da, 0xfd750047, 0xfd7ae120, 0xfd809612, 0xfd8620b4,
|
||||
0xfd8b8285, 0xfd90bcf5, 0xfd95d15e, 0xfd9ac10b, 0xfd9f8d36,
|
||||
0xfda43708, 0xfda8bf9e, 0xfdad2806, 0xfdb17141, 0xfdb59c46,
|
||||
0xfdb9a9fd, 0xfdbd9b46, 0xfdc170f6, 0xfdc52bd8, 0xfdc8ccac,
|
||||
0xfdcc542d, 0xfdcfc30b, 0xfdd319ef, 0xfdd6597a, 0xfdd98245,
|
||||
0xfddc94e5, 0xfddf91e6, 0xfde279ce, 0xfde54d1f, 0xfde80c52,
|
||||
0xfdeab7de, 0xfded5034, 0xfdefd5be, 0xfdf248e3, 0xfdf4aa06,
|
||||
0xfdf6f984, 0xfdf937b6, 0xfdfb64f4, 0xfdfd818d, 0xfdff8dd0,
|
||||
0xfe018a08, 0xfe03767a, 0xfe05536c, 0xfe07211c, 0xfe08dfc9,
|
||||
0xfe0a8fab, 0xfe0c30fb, 0xfe0dc3ec, 0xfe0f48b1, 0xfe10bf76,
|
||||
0xfe122869, 0xfe1383b4, 0xfe14d17c, 0xfe1611e7, 0xfe174516,
|
||||
0xfe186b2a, 0xfe19843e, 0xfe1a9070, 0xfe1b8fd6, 0xfe1c8289,
|
||||
0xfe1d689b, 0xfe1e4220, 0xfe1f0f26, 0xfe1fcfbc, 0xfe2083ed,
|
||||
0xfe212bc3, 0xfe21c745, 0xfe225678, 0xfe22d95f, 0xfe234ffb,
|
||||
0xfe23ba4a, 0xfe241849, 0xfe2469f2, 0xfe24af3c, 0xfe24e81e,
|
||||
0xfe25148b, 0xfe253474, 0xfe2547c7, 0xfe254e70, 0xfe25485a,
|
||||
0xfe25356a, 0xfe251586, 0xfe24e88f, 0xfe24ae64, 0xfe2466e1,
|
||||
0xfe2411df, 0xfe23af34, 0xfe233eb4, 0xfe22c02c, 0xfe22336b,
|
||||
0xfe219838, 0xfe20ee58, 0xfe20358c, 0xfe1f6d92, 0xfe1e9621,
|
||||
0xfe1daef0, 0xfe1cb7ac, 0xfe1bb002, 0xfe1a9798, 0xfe196e0d,
|
||||
0xfe1832fd, 0xfe16e5fe, 0xfe15869d, 0xfe141464, 0xfe128ed3,
|
||||
0xfe10f565, 0xfe0f478c, 0xfe0d84b1, 0xfe0bac36, 0xfe09bd73,
|
||||
0xfe07b7b5, 0xfe059a40, 0xfe03644c, 0xfe011504, 0xfdfeab88,
|
||||
0xfdfc26e9, 0xfdf98629, 0xfdf6c83b, 0xfdf3ec01, 0xfdf0f04a,
|
||||
0xfdedd3d1, 0xfdea953d, 0xfde7331e, 0xfde3abe9, 0xfddffdfb,
|
||||
0xfddc2791, 0xfdd826cd, 0xfdd3f9a8, 0xfdcf9dfc, 0xfdcb1176,
|
||||
0xfdc65198, 0xfdc15bb3, 0xfdbc2ce2, 0xfdb6c206, 0xfdb117be,
|
||||
0xfdab2a63, 0xfda4f5fd, 0xfd9e7640, 0xfd97a67a, 0xfd908192,
|
||||
0xfd8901f2, 0xfd812182, 0xfd78d98e, 0xfd7022bb, 0xfd66f4ed,
|
||||
0xfd5d4732, 0xfd530f9c, 0xfd48432b, 0xfd3cd59a, 0xfd30b936,
|
||||
0xfd23dea4, 0xfd16349e, 0xfd07a7a3, 0xfcf8219b, 0xfce7895b,
|
||||
0xfcd5c220, 0xfcc2aadb, 0xfcae1d5e, 0xfc97ed4e, 0xfc7fe6d4,
|
||||
0xfc65ccf3, 0xfc495762, 0xfc2a2fc8, 0xfc07ee19, 0xfbe213c1,
|
||||
0xfbb8051a, 0xfb890078, 0xfb5411a5, 0xfb180005, 0xfad33482,
|
||||
0xfa839276, 0xfa263b32, 0xf9b72d1c, 0xf930a1a2, 0xf889f023,
|
||||
0xf7b577d2, 0xf69c650c, 0xf51530f0, 0xf2cb0e3c, 0xeeefb15d,
|
||||
0xe6da6ecf,
|
||||
}
|
||||
|
||||
var we = [256]float32{
|
||||
2.0249555e-09, 1.486674e-11, 2.4409617e-11, 3.1968806e-11,
|
||||
3.844677e-11, 4.4228204e-11, 4.9516443e-11, 5.443359e-11,
|
||||
5.905944e-11, 6.344942e-11, 6.7643814e-11, 7.1672945e-11,
|
||||
7.556032e-11, 7.932458e-11, 8.298079e-11, 8.654132e-11,
|
||||
9.0016515e-11, 9.3415074e-11, 9.674443e-11, 1.0001099e-10,
|
||||
1.03220314e-10, 1.06377254e-10, 1.09486115e-10, 1.1255068e-10,
|
||||
1.1557435e-10, 1.1856015e-10, 1.2151083e-10, 1.2442886e-10,
|
||||
1.2731648e-10, 1.3017575e-10, 1.3300853e-10, 1.3581657e-10,
|
||||
1.3860142e-10, 1.4136457e-10, 1.4410738e-10, 1.4683108e-10,
|
||||
1.4953687e-10, 1.5222583e-10, 1.54899e-10, 1.5755733e-10,
|
||||
1.6020171e-10, 1.6283301e-10, 1.6545203e-10, 1.6805951e-10,
|
||||
1.7065617e-10, 1.732427e-10, 1.7581973e-10, 1.7838787e-10,
|
||||
1.8094774e-10, 1.8349985e-10, 1.8604476e-10, 1.8858298e-10,
|
||||
1.9111498e-10, 1.9364126e-10, 1.9616223e-10, 1.9867835e-10,
|
||||
2.0119004e-10, 2.0369768e-10, 2.0620168e-10, 2.087024e-10,
|
||||
2.1120022e-10, 2.136955e-10, 2.1618855e-10, 2.1867974e-10,
|
||||
2.2116936e-10, 2.2365775e-10, 2.261452e-10, 2.2863202e-10,
|
||||
2.311185e-10, 2.3360494e-10, 2.360916e-10, 2.3857874e-10,
|
||||
2.4106667e-10, 2.4355562e-10, 2.4604588e-10, 2.485377e-10,
|
||||
2.5103128e-10, 2.5352695e-10, 2.560249e-10, 2.585254e-10,
|
||||
2.6102867e-10, 2.6353494e-10, 2.6604446e-10, 2.6855745e-10,
|
||||
2.7107416e-10, 2.7359479e-10, 2.761196e-10, 2.7864877e-10,
|
||||
2.8118255e-10, 2.8372119e-10, 2.8626485e-10, 2.888138e-10,
|
||||
2.9136826e-10, 2.939284e-10, 2.9649452e-10, 2.9906677e-10,
|
||||
3.016454e-10, 3.0423064e-10, 3.0682268e-10, 3.0942177e-10,
|
||||
3.1202813e-10, 3.1464195e-10, 3.1726352e-10, 3.19893e-10,
|
||||
3.2253064e-10, 3.251767e-10, 3.2783135e-10, 3.3049485e-10,
|
||||
3.3316744e-10, 3.3584938e-10, 3.3854083e-10, 3.4124212e-10,
|
||||
3.4395342e-10, 3.46675e-10, 3.4940711e-10, 3.5215003e-10,
|
||||
3.5490397e-10, 3.5766917e-10, 3.6044595e-10, 3.6323455e-10,
|
||||
3.660352e-10, 3.6884823e-10, 3.7167386e-10, 3.745124e-10,
|
||||
3.773641e-10, 3.802293e-10, 3.8310827e-10, 3.860013e-10,
|
||||
3.8890866e-10, 3.918307e-10, 3.9476775e-10, 3.9772008e-10,
|
||||
4.0068804e-10, 4.0367196e-10, 4.0667217e-10, 4.09689e-10,
|
||||
4.1272286e-10, 4.1577405e-10, 4.1884296e-10, 4.2192994e-10,
|
||||
4.250354e-10, 4.281597e-10, 4.313033e-10, 4.3446652e-10,
|
||||
4.3764986e-10, 4.408537e-10, 4.4407847e-10, 4.4732465e-10,
|
||||
4.5059267e-10, 4.5388301e-10, 4.571962e-10, 4.6053267e-10,
|
||||
4.6389292e-10, 4.6727755e-10, 4.70687e-10, 4.741219e-10,
|
||||
4.7758275e-10, 4.810702e-10, 4.845848e-10, 4.8812715e-10,
|
||||
4.9169796e-10, 4.9529775e-10, 4.989273e-10, 5.0258725e-10,
|
||||
5.0627835e-10, 5.100013e-10, 5.1375687e-10, 5.1754584e-10,
|
||||
5.21369e-10, 5.2522725e-10, 5.2912136e-10, 5.330522e-10,
|
||||
5.370208e-10, 5.4102806e-10, 5.45075e-10, 5.491625e-10,
|
||||
5.532918e-10, 5.5746385e-10, 5.616799e-10, 5.6594107e-10,
|
||||
5.7024857e-10, 5.746037e-10, 5.7900773e-10, 5.834621e-10,
|
||||
5.8796823e-10, 5.925276e-10, 5.971417e-10, 6.018122e-10,
|
||||
6.065408e-10, 6.113292e-10, 6.1617933e-10, 6.2109295e-10,
|
||||
6.260722e-10, 6.3111916e-10, 6.3623595e-10, 6.4142497e-10,
|
||||
6.4668854e-10, 6.5202926e-10, 6.5744976e-10, 6.6295286e-10,
|
||||
6.6854156e-10, 6.742188e-10, 6.79988e-10, 6.858526e-10,
|
||||
6.9181616e-10, 6.978826e-10, 7.04056e-10, 7.103407e-10,
|
||||
7.167412e-10, 7.2326256e-10, 7.2990985e-10, 7.366886e-10,
|
||||
7.4360473e-10, 7.5066453e-10, 7.5787476e-10, 7.6524265e-10,
|
||||
7.7277595e-10, 7.80483e-10, 7.883728e-10, 7.9645507e-10,
|
||||
8.047402e-10, 8.1323964e-10, 8.219657e-10, 8.309319e-10,
|
||||
8.401528e-10, 8.496445e-10, 8.594247e-10, 8.6951274e-10,
|
||||
8.799301e-10, 8.9070046e-10, 9.018503e-10, 9.134092e-10,
|
||||
9.254101e-10, 9.378904e-10, 9.508923e-10, 9.644638e-10,
|
||||
9.786603e-10, 9.935448e-10, 1.0091913e-09, 1.025686e-09,
|
||||
1.0431306e-09, 1.0616465e-09, 1.08138e-09, 1.1025096e-09,
|
||||
1.1252564e-09, 1.1498986e-09, 1.1767932e-09, 1.206409e-09,
|
||||
1.2393786e-09, 1.276585e-09, 1.3193139e-09, 1.3695435e-09,
|
||||
1.4305498e-09, 1.508365e-09, 1.6160854e-09, 1.7921248e-09,
|
||||
}
|
||||
|
||||
var fe = [256]float32{
|
||||
1, 0.9381437, 0.90046996, 0.87170434, 0.8477855, 0.8269933,
|
||||
0.8084217, 0.7915276, 0.77595687, 0.7614634, 0.7478686,
|
||||
0.7350381, 0.72286767, 0.71127474, 0.70019263, 0.6895665,
|
||||
0.67935055, 0.6695063, 0.66000086, 0.65080583, 0.6418967,
|
||||
0.63325197, 0.6248527, 0.6166822, 0.60872537, 0.60096896,
|
||||
0.5934009, 0.58601034, 0.5787874, 0.57172304, 0.5648092,
|
||||
0.5580383, 0.5514034, 0.5448982, 0.5385169, 0.53225386,
|
||||
0.5261042, 0.52006316, 0.5141264, 0.50828975, 0.5025495,
|
||||
0.496902, 0.49134386, 0.485872, 0.48048335, 0.4751752,
|
||||
0.46994483, 0.46478975, 0.45970762, 0.45469615, 0.44975325,
|
||||
0.44487688, 0.44006512, 0.43531612, 0.43062815, 0.42599955,
|
||||
0.42142874, 0.4169142, 0.41245446, 0.40804818, 0.403694,
|
||||
0.3993907, 0.39513698, 0.39093173, 0.38677382, 0.38266218,
|
||||
0.37859577, 0.37457356, 0.37059465, 0.3666581, 0.362763,
|
||||
0.35890847, 0.35509375, 0.351318, 0.3475805, 0.34388044,
|
||||
0.34021714, 0.3365899, 0.33299807, 0.32944095, 0.32591796,
|
||||
0.3224285, 0.3189719, 0.31554767, 0.31215525, 0.30879408,
|
||||
0.3054636, 0.3021634, 0.29889292, 0.2956517, 0.29243928,
|
||||
0.28925523, 0.28609908, 0.28297043, 0.27986884, 0.27679393,
|
||||
0.2737453, 0.2707226, 0.2677254, 0.26475343, 0.26180625,
|
||||
0.25888354, 0.25598502, 0.2531103, 0.25025907, 0.24743107,
|
||||
0.24462597, 0.24184346, 0.23908329, 0.23634516, 0.23362878,
|
||||
0.23093392, 0.2282603, 0.22560766, 0.22297576, 0.22036438,
|
||||
0.21777324, 0.21520215, 0.21265087, 0.21011916, 0.20760682,
|
||||
0.20511365, 0.20263945, 0.20018397, 0.19774707, 0.19532852,
|
||||
0.19292815, 0.19054577, 0.1881812, 0.18583426, 0.18350479,
|
||||
0.1811926, 0.17889754, 0.17661946, 0.17435817, 0.17211354,
|
||||
0.1698854, 0.16767362, 0.16547804, 0.16329853, 0.16113494,
|
||||
0.15898713, 0.15685499, 0.15473837, 0.15263714, 0.15055119,
|
||||
0.14848037, 0.14642459, 0.14438373, 0.14235765, 0.14034624,
|
||||
0.13834943, 0.13636707, 0.13439907, 0.13244532, 0.13050574,
|
||||
0.1285802, 0.12666863, 0.12477092, 0.12288698, 0.12101672,
|
||||
0.119160056, 0.1173169, 0.115487166, 0.11367077, 0.11186763,
|
||||
0.11007768, 0.10830083, 0.10653701, 0.10478614, 0.10304816,
|
||||
0.101323, 0.09961058, 0.09791085, 0.09622374, 0.09454919,
|
||||
0.09288713, 0.091237515, 0.08960028, 0.087975375, 0.08636274,
|
||||
0.08476233, 0.083174095, 0.081597984, 0.08003395, 0.07848195,
|
||||
0.076941945, 0.07541389, 0.07389775, 0.072393484, 0.07090106,
|
||||
0.069420435, 0.06795159, 0.066494495, 0.06504912, 0.063615434,
|
||||
0.062193416, 0.060783047, 0.059384305, 0.057997175,
|
||||
0.05662164, 0.05525769, 0.053905312, 0.052564494, 0.051235236,
|
||||
0.049917534, 0.048611384, 0.047316793, 0.046033762, 0.0447623,
|
||||
0.043502413, 0.042254124, 0.041017443, 0.039792392,
|
||||
0.038578995, 0.037377283, 0.036187284, 0.035009038,
|
||||
0.033842582, 0.032687962, 0.031545233, 0.030414443, 0.02929566,
|
||||
0.02818895, 0.027094385, 0.026012046, 0.024942026, 0.023884421,
|
||||
0.022839336, 0.021806888, 0.020787204, 0.019780423, 0.0187867,
|
||||
0.0178062, 0.016839107, 0.015885621, 0.014945968, 0.014020392,
|
||||
0.013109165, 0.012212592, 0.011331013, 0.01046481, 0.009614414,
|
||||
0.008780315, 0.007963077, 0.0071633533, 0.006381906,
|
||||
0.0056196423, 0.0048776558, 0.004157295, 0.0034602648,
|
||||
0.0027887989, 0.0021459677, 0.0015362998, 0.0009672693,
|
||||
0.00045413437,
|
||||
}
|
||||
160
server/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/normal.go
generated
vendored
Normal file
160
server/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/normal.go
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
// Copied from https://cs.opensource.google/go/x/exp/+/24438e51023af3bfc1db8aed43c1342817e8cfcd:rand/normal.go
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rand
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
* Normal distribution
|
||||
*
|
||||
* See "The Ziggurat Method for Generating Random Variables"
|
||||
* (Marsaglia & Tsang, 2000)
|
||||
* http://www.jstatsoft.org/v05/i08/paper [pdf]
|
||||
*/
|
||||
|
||||
const (
|
||||
rn = 3.442619855899
|
||||
)
|
||||
|
||||
func absInt32(i int32) uint32 {
|
||||
if i < 0 {
|
||||
return uint32(-i)
|
||||
}
|
||||
return uint32(i)
|
||||
}
|
||||
|
||||
// NormFloat64 returns a normally distributed float64 in the range
|
||||
// [-math.MaxFloat64, +math.MaxFloat64] with
|
||||
// standard normal distribution (mean = 0, stddev = 1).
|
||||
// To produce a different normal distribution, callers can
|
||||
// adjust the output using:
|
||||
//
|
||||
// sample = NormFloat64() * desiredStdDev + desiredMean
|
||||
func (r *Rand) NormFloat64() float64 {
|
||||
for {
|
||||
j := int32(r.Uint32()) // Possibly negative
|
||||
i := j & 0x7F
|
||||
x := float64(j) * float64(wn[i])
|
||||
if absInt32(j) < kn[i] {
|
||||
// This case should be hit better than 99% of the time.
|
||||
return x
|
||||
}
|
||||
|
||||
if i == 0 {
|
||||
// This extra work is only required for the base strip.
|
||||
for {
|
||||
x = -math.Log(r.Float64()) * (1.0 / rn)
|
||||
y := -math.Log(r.Float64())
|
||||
if y+y >= x*x {
|
||||
break
|
||||
}
|
||||
}
|
||||
if j > 0 {
|
||||
return rn + x
|
||||
}
|
||||
return -rn - x
|
||||
}
|
||||
if fn[i]+float32(r.Float64())*(fn[i-1]-fn[i]) < float32(math.Exp(-.5*x*x)) {
|
||||
return x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var kn = [128]uint32{
|
||||
0x76ad2212, 0x0, 0x600f1b53, 0x6ce447a6, 0x725b46a2,
|
||||
0x7560051d, 0x774921eb, 0x789a25bd, 0x799045c3, 0x7a4bce5d,
|
||||
0x7adf629f, 0x7b5682a6, 0x7bb8a8c6, 0x7c0ae722, 0x7c50cce7,
|
||||
0x7c8cec5b, 0x7cc12cd6, 0x7ceefed2, 0x7d177e0b, 0x7d3b8883,
|
||||
0x7d5bce6c, 0x7d78dd64, 0x7d932886, 0x7dab0e57, 0x7dc0dd30,
|
||||
0x7dd4d688, 0x7de73185, 0x7df81cea, 0x7e07c0a3, 0x7e163efa,
|
||||
0x7e23b587, 0x7e303dfd, 0x7e3beec2, 0x7e46db77, 0x7e51155d,
|
||||
0x7e5aabb3, 0x7e63abf7, 0x7e6c222c, 0x7e741906, 0x7e7b9a18,
|
||||
0x7e82adfa, 0x7e895c63, 0x7e8fac4b, 0x7e95a3fb, 0x7e9b4924,
|
||||
0x7ea0a0ef, 0x7ea5b00d, 0x7eaa7ac3, 0x7eaf04f3, 0x7eb3522a,
|
||||
0x7eb765a5, 0x7ebb4259, 0x7ebeeafd, 0x7ec2620a, 0x7ec5a9c4,
|
||||
0x7ec8c441, 0x7ecbb365, 0x7ece78ed, 0x7ed11671, 0x7ed38d62,
|
||||
0x7ed5df12, 0x7ed80cb4, 0x7eda175c, 0x7edc0005, 0x7eddc78e,
|
||||
0x7edf6ebf, 0x7ee0f647, 0x7ee25ebe, 0x7ee3a8a9, 0x7ee4d473,
|
||||
0x7ee5e276, 0x7ee6d2f5, 0x7ee7a620, 0x7ee85c10, 0x7ee8f4cd,
|
||||
0x7ee97047, 0x7ee9ce59, 0x7eea0eca, 0x7eea3147, 0x7eea3568,
|
||||
0x7eea1aab, 0x7ee9e071, 0x7ee98602, 0x7ee90a88, 0x7ee86d08,
|
||||
0x7ee7ac6a, 0x7ee6c769, 0x7ee5bc9c, 0x7ee48a67, 0x7ee32efc,
|
||||
0x7ee1a857, 0x7edff42f, 0x7ede0ffa, 0x7edbf8d9, 0x7ed9ab94,
|
||||
0x7ed7248d, 0x7ed45fae, 0x7ed1585c, 0x7ece095f, 0x7eca6ccb,
|
||||
0x7ec67be2, 0x7ec22eee, 0x7ebd7d1a, 0x7eb85c35, 0x7eb2c075,
|
||||
0x7eac9c20, 0x7ea5df27, 0x7e9e769f, 0x7e964c16, 0x7e8d44ba,
|
||||
0x7e834033, 0x7e781728, 0x7e6b9933, 0x7e5d8a1a, 0x7e4d9ded,
|
||||
0x7e3b737a, 0x7e268c2f, 0x7e0e3ff5, 0x7df1aa5d, 0x7dcf8c72,
|
||||
0x7da61a1e, 0x7d72a0fb, 0x7d30e097, 0x7cd9b4ab, 0x7c600f1a,
|
||||
0x7ba90bdc, 0x7a722176, 0x77d664e5,
|
||||
}
|
||||
|
||||
var wn = [128]float32{
|
||||
1.7290405e-09, 1.2680929e-10, 1.6897518e-10, 1.9862688e-10,
|
||||
2.2232431e-10, 2.4244937e-10, 2.601613e-10, 2.7611988e-10,
|
||||
2.9073963e-10, 3.042997e-10, 3.1699796e-10, 3.289802e-10,
|
||||
3.4035738e-10, 3.5121603e-10, 3.616251e-10, 3.7164058e-10,
|
||||
3.8130857e-10, 3.9066758e-10, 3.9975012e-10, 4.08584e-10,
|
||||
4.1719309e-10, 4.2559822e-10, 4.338176e-10, 4.418672e-10,
|
||||
4.497613e-10, 4.5751258e-10, 4.651324e-10, 4.7263105e-10,
|
||||
4.8001775e-10, 4.87301e-10, 4.944885e-10, 5.015873e-10,
|
||||
5.0860405e-10, 5.155446e-10, 5.2241467e-10, 5.2921934e-10,
|
||||
5.359635e-10, 5.426517e-10, 5.4928817e-10, 5.5587696e-10,
|
||||
5.624219e-10, 5.6892646e-10, 5.753941e-10, 5.818282e-10,
|
||||
5.882317e-10, 5.946077e-10, 6.00959e-10, 6.072884e-10,
|
||||
6.135985e-10, 6.19892e-10, 6.2617134e-10, 6.3243905e-10,
|
||||
6.386974e-10, 6.449488e-10, 6.511956e-10, 6.5744005e-10,
|
||||
6.6368433e-10, 6.699307e-10, 6.7618144e-10, 6.824387e-10,
|
||||
6.8870465e-10, 6.949815e-10, 7.012715e-10, 7.075768e-10,
|
||||
7.1389966e-10, 7.202424e-10, 7.266073e-10, 7.329966e-10,
|
||||
7.394128e-10, 7.4585826e-10, 7.5233547e-10, 7.58847e-10,
|
||||
7.653954e-10, 7.719835e-10, 7.7861395e-10, 7.852897e-10,
|
||||
7.920138e-10, 7.987892e-10, 8.0561924e-10, 8.125073e-10,
|
||||
8.194569e-10, 8.2647167e-10, 8.3355556e-10, 8.407127e-10,
|
||||
8.479473e-10, 8.55264e-10, 8.6266755e-10, 8.7016316e-10,
|
||||
8.777562e-10, 8.8545243e-10, 8.932582e-10, 9.0117996e-10,
|
||||
9.09225e-10, 9.174008e-10, 9.2571584e-10, 9.341788e-10,
|
||||
9.427997e-10, 9.515889e-10, 9.605579e-10, 9.697193e-10,
|
||||
9.790869e-10, 9.88676e-10, 9.985036e-10, 1.0085882e-09,
|
||||
1.0189509e-09, 1.0296151e-09, 1.0406069e-09, 1.0519566e-09,
|
||||
1.063698e-09, 1.0758702e-09, 1.0885183e-09, 1.1016947e-09,
|
||||
1.1154611e-09, 1.1298902e-09, 1.1450696e-09, 1.1611052e-09,
|
||||
1.1781276e-09, 1.1962995e-09, 1.2158287e-09, 1.2369856e-09,
|
||||
1.2601323e-09, 1.2857697e-09, 1.3146202e-09, 1.347784e-09,
|
||||
1.3870636e-09, 1.4357403e-09, 1.5008659e-09, 1.6030948e-09,
|
||||
}
|
||||
|
||||
var fn = [128]float32{
|
||||
1, 0.9635997, 0.9362827, 0.9130436, 0.89228165, 0.87324303,
|
||||
0.8555006, 0.8387836, 0.8229072, 0.8077383, 0.793177,
|
||||
0.7791461, 0.7655842, 0.7524416, 0.73967725, 0.7272569,
|
||||
0.7151515, 0.7033361, 0.69178915, 0.68049186, 0.6694277,
|
||||
0.658582, 0.6479418, 0.63749546, 0.6272325, 0.6171434,
|
||||
0.6072195, 0.5974532, 0.58783704, 0.5783647, 0.56903,
|
||||
0.5598274, 0.5507518, 0.54179835, 0.5329627, 0.52424055,
|
||||
0.5156282, 0.50712204, 0.49871865, 0.49041483, 0.48220766,
|
||||
0.4740943, 0.46607214, 0.4581387, 0.45029163, 0.44252872,
|
||||
0.43484783, 0.427247, 0.41972435, 0.41227803, 0.40490642,
|
||||
0.39760786, 0.3903808, 0.3832238, 0.37613547, 0.36911446,
|
||||
0.3621595, 0.35526937, 0.34844297, 0.34167916, 0.33497685,
|
||||
0.3283351, 0.3217529, 0.3152294, 0.30876362, 0.30235484,
|
||||
0.29600215, 0.28970486, 0.2834622, 0.2772735, 0.27113807,
|
||||
0.2650553, 0.25902456, 0.2530453, 0.24711695, 0.241239,
|
||||
0.23541094, 0.22963232, 0.2239027, 0.21822165, 0.21258877,
|
||||
0.20700371, 0.20146611, 0.19597565, 0.19053204, 0.18513499,
|
||||
0.17978427, 0.17447963, 0.1692209, 0.16400786, 0.15884037,
|
||||
0.15371831, 0.14864157, 0.14361008, 0.13862377, 0.13368265,
|
||||
0.12878671, 0.12393598, 0.119130544, 0.11437051, 0.10965602,
|
||||
0.104987256, 0.10036444, 0.095787846, 0.0912578, 0.08677467,
|
||||
0.0823389, 0.077950984, 0.073611505, 0.06932112, 0.06508058,
|
||||
0.06089077, 0.056752663, 0.0526674, 0.048636295, 0.044660863,
|
||||
0.040742867, 0.03688439, 0.033087887, 0.029356318,
|
||||
0.025693292, 0.022103304, 0.018592102, 0.015167298,
|
||||
0.011839478, 0.008624485, 0.005548995, 0.0026696292,
|
||||
}
|
||||
374
server/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/rand.go
generated
vendored
Normal file
374
server/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/rand.go
generated
vendored
Normal file
@@ -0,0 +1,374 @@
|
||||
// Copied from https://cs.opensource.google/go/x/exp/+/24438e51023af3bfc1db8aed43c1342817e8cfcd:rand/rand.go
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package rand implements pseudo-random number generators.
|
||||
//
|
||||
// Random numbers are generated by a Source. Top-level functions, such as
|
||||
// Float64 and Int, use a default shared Source that produces a deterministic
|
||||
// sequence of values each time a program is run. Use the Seed function to
|
||||
// initialize the default Source if different behavior is required for each run.
|
||||
// The default Source, a LockedSource, is safe for concurrent use by multiple
|
||||
// goroutines, but Sources created by NewSource are not. However, Sources are small
|
||||
// and it is reasonable to have a separate Source for each goroutine, seeded
|
||||
// differently, to avoid locking.
|
||||
//
|
||||
// For random numbers suitable for security-sensitive work, see the crypto/rand
|
||||
// package.
|
||||
package rand
|
||||
|
||||
import "sync"
|
||||
|
||||
// A Source represents a source of uniformly-distributed
|
||||
// pseudo-random int64 values in the range [0, 1<<64).
|
||||
type Source interface {
|
||||
Uint64() uint64
|
||||
Seed(seed uint64)
|
||||
}
|
||||
|
||||
// NewSource returns a new pseudo-random Source seeded with the given value.
|
||||
func NewSource(seed uint64) Source {
|
||||
var rng PCGSource
|
||||
rng.Seed(seed)
|
||||
return &rng
|
||||
}
|
||||
|
||||
// A Rand is a source of random numbers.
|
||||
type Rand struct {
|
||||
src Source
|
||||
|
||||
// readVal contains remainder of 64-bit integer used for bytes
|
||||
// generation during most recent Read call.
|
||||
// It is saved so next Read call can start where the previous
|
||||
// one finished.
|
||||
readVal uint64
|
||||
// readPos indicates the number of low-order bytes of readVal
|
||||
// that are still valid.
|
||||
readPos int8
|
||||
}
|
||||
|
||||
// New returns a new Rand that uses random values from src
|
||||
// to generate other random values.
|
||||
func New(src Source) *Rand {
|
||||
return &Rand{src: src}
|
||||
}
|
||||
|
||||
// Seed uses the provided seed value to initialize the generator to a deterministic state.
|
||||
// Seed should not be called concurrently with any other Rand method.
|
||||
func (r *Rand) Seed(seed uint64) {
|
||||
if lk, ok := r.src.(*LockedSource); ok {
|
||||
lk.seedPos(seed, &r.readPos)
|
||||
return
|
||||
}
|
||||
|
||||
r.src.Seed(seed)
|
||||
r.readPos = 0
|
||||
}
|
||||
|
||||
// Uint64 returns a pseudo-random 64-bit integer as a uint64.
|
||||
func (r *Rand) Uint64() uint64 { return r.src.Uint64() }
|
||||
|
||||
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
|
||||
func (r *Rand) Int63() int64 { return int64(r.src.Uint64() &^ (1 << 63)) }
|
||||
|
||||
// Uint32 returns a pseudo-random 32-bit value as a uint32.
|
||||
func (r *Rand) Uint32() uint32 { return uint32(r.Uint64() >> 32) }
|
||||
|
||||
// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
|
||||
func (r *Rand) Int31() int32 { return int32(r.Uint64() >> 33) }
|
||||
|
||||
// Int returns a non-negative pseudo-random int.
|
||||
func (r *Rand) Int() int {
|
||||
u := uint(r.Uint64())
|
||||
return int(u << 1 >> 1) // clear sign bit.
|
||||
}
|
||||
|
||||
const maxUint64 = (1 << 64) - 1
|
||||
|
||||
// Uint64n returns, as a uint64, a pseudo-random number in [0,n).
|
||||
// It is guaranteed more uniform than taking a Source value mod n
|
||||
// for any n that is not a power of 2.
|
||||
func (r *Rand) Uint64n(n uint64) uint64 {
|
||||
if n&(n-1) == 0 { // n is power of two, can mask
|
||||
if n == 0 {
|
||||
panic("invalid argument to Uint64n")
|
||||
}
|
||||
return r.Uint64() & (n - 1)
|
||||
}
|
||||
// If n does not divide v, to avoid bias we must not use
|
||||
// a v that is within maxUint64%n of the top of the range.
|
||||
v := r.Uint64()
|
||||
if v > maxUint64-n { // Fast check.
|
||||
ceiling := maxUint64 - maxUint64%n
|
||||
for v >= ceiling {
|
||||
v = r.Uint64()
|
||||
}
|
||||
}
|
||||
|
||||
return v % n
|
||||
}
|
||||
|
||||
// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
|
||||
// It panics if n <= 0.
|
||||
func (r *Rand) Int63n(n int64) int64 {
|
||||
if n <= 0 {
|
||||
panic("invalid argument to Int63n")
|
||||
}
|
||||
return int64(r.Uint64n(uint64(n)))
|
||||
}
|
||||
|
||||
// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
|
||||
// It panics if n <= 0.
|
||||
func (r *Rand) Int31n(n int32) int32 {
|
||||
if n <= 0 {
|
||||
panic("invalid argument to Int31n")
|
||||
}
|
||||
// TODO: Avoid some 64-bit ops to make it more efficient on 32-bit machines.
|
||||
return int32(r.Uint64n(uint64(n)))
|
||||
}
|
||||
|
||||
// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
|
||||
// It panics if n <= 0.
|
||||
func (r *Rand) Intn(n int) int {
|
||||
if n <= 0 {
|
||||
panic("invalid argument to Intn")
|
||||
}
|
||||
// TODO: Avoid some 64-bit ops to make it more efficient on 32-bit machines.
|
||||
return int(r.Uint64n(uint64(n)))
|
||||
}
|
||||
|
||||
// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
|
||||
func (r *Rand) Float64() float64 {
|
||||
// There is one bug in the value stream: r.Int63() may be so close
|
||||
// to 1<<63 that the division rounds up to 1.0, and we've guaranteed
|
||||
// that the result is always less than 1.0.
|
||||
//
|
||||
// We tried to fix this by mapping 1.0 back to 0.0, but since float64
|
||||
// values near 0 are much denser than near 1, mapping 1 to 0 caused
|
||||
// a theoretically significant overshoot in the probability of returning 0.
|
||||
// Instead of that, if we round up to 1, just try again.
|
||||
// Getting 1 only happens 1/2⁵³ of the time, so most clients
|
||||
// will not observe it anyway.
|
||||
again:
|
||||
f := float64(r.Uint64n(1<<53)) / (1 << 53)
|
||||
if f == 1.0 {
|
||||
goto again // resample; this branch is taken O(never)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
|
||||
func (r *Rand) Float32() float32 {
|
||||
// We do not want to return 1.0.
|
||||
// This only happens 1/2²⁴ of the time (plus the 1/2⁵³ of the time in Float64).
|
||||
again:
|
||||
f := float32(r.Float64())
|
||||
if f == 1 {
|
||||
goto again // resample; this branch is taken O(very rarely)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
|
||||
func (r *Rand) Perm(n int) []int {
|
||||
m := make([]int, n)
|
||||
// In the following loop, the iteration when i=0 always swaps m[0] with m[0].
|
||||
// A change to remove this useless iteration is to assign 1 to i in the init
|
||||
// statement. But Perm also effects r. Making this change will affect
|
||||
// the final state of r. So this change can't be made for compatibility
|
||||
// reasons for Go 1.
|
||||
for i := 0; i < n; i++ {
|
||||
j := r.Intn(i + 1)
|
||||
m[i] = m[j]
|
||||
m[j] = i
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// Shuffle pseudo-randomizes the order of elements.
|
||||
// n is the number of elements. Shuffle panics if n < 0.
|
||||
// swap swaps the elements with indexes i and j.
|
||||
func (r *Rand) Shuffle(n int, swap func(i, j int)) {
|
||||
if n < 0 {
|
||||
panic("invalid argument to Shuffle")
|
||||
}
|
||||
|
||||
// Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
|
||||
// Shuffle really ought not be called with n that doesn't fit in 32 bits.
|
||||
// Not only will it take a very long time, but with 2³¹! possible permutations,
|
||||
// there's no way that any PRNG can have a big enough internal state to
|
||||
// generate even a minuscule percentage of the possible permutations.
|
||||
// Nevertheless, the right API signature accepts an int n, so handle it as best we can.
|
||||
i := n - 1
|
||||
for ; i > 1<<31-1-1; i-- {
|
||||
j := int(r.Int63n(int64(i + 1)))
|
||||
swap(i, j)
|
||||
}
|
||||
for ; i > 0; i-- {
|
||||
j := int(r.Int31n(int32(i + 1)))
|
||||
swap(i, j)
|
||||
}
|
||||
}
|
||||
|
||||
// Read generates len(p) random bytes and writes them into p. It
|
||||
// always returns len(p) and a nil error.
|
||||
// Read should not be called concurrently with any other Rand method unless
|
||||
// the underlying source is a LockedSource.
|
||||
func (r *Rand) Read(p []byte) (n int, err error) {
|
||||
if lk, ok := r.src.(*LockedSource); ok {
|
||||
return lk.Read(p, &r.readVal, &r.readPos)
|
||||
}
|
||||
return read(p, r.src, &r.readVal, &r.readPos)
|
||||
}
|
||||
|
||||
func read(p []byte, src Source, readVal *uint64, readPos *int8) (n int, err error) {
|
||||
pos := *readPos
|
||||
val := *readVal
|
||||
rng, _ := src.(*PCGSource)
|
||||
for n = 0; n < len(p); n++ {
|
||||
if pos == 0 {
|
||||
if rng != nil {
|
||||
val = rng.Uint64()
|
||||
} else {
|
||||
val = src.Uint64()
|
||||
}
|
||||
pos = 8
|
||||
}
|
||||
p[n] = byte(val)
|
||||
val >>= 8
|
||||
pos--
|
||||
}
|
||||
*readPos = pos
|
||||
*readVal = val
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
* Top-level convenience functions
|
||||
*/
|
||||
|
||||
var globalRand = New(&LockedSource{src: *NewSource(1).(*PCGSource)})
|
||||
|
||||
// Type assert that globalRand's source is a LockedSource whose src is a PCGSource.
|
||||
var _ PCGSource = globalRand.src.(*LockedSource).src
|
||||
|
||||
// Seed uses the provided seed value to initialize the default Source to a
|
||||
// deterministic state. If Seed is not called, the generator behaves as
|
||||
// if seeded by Seed(1).
|
||||
// Seed, unlike the Rand.Seed method, is safe for concurrent use.
|
||||
func Seed(seed uint64) { globalRand.Seed(seed) }
|
||||
|
||||
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64
|
||||
// from the default Source.
|
||||
func Int63() int64 { return globalRand.Int63() }
|
||||
|
||||
// Uint32 returns a pseudo-random 32-bit value as a uint32
|
||||
// from the default Source.
|
||||
func Uint32() uint32 { return globalRand.Uint32() }
|
||||
|
||||
// Uint64 returns a pseudo-random 64-bit value as a uint64
|
||||
// from the default Source.
|
||||
func Uint64() uint64 { return globalRand.Uint64() }
|
||||
|
||||
// Int31 returns a non-negative pseudo-random 31-bit integer as an int32
|
||||
// from the default Source.
|
||||
func Int31() int32 { return globalRand.Int31() }
|
||||
|
||||
// Int returns a non-negative pseudo-random int from the default Source.
|
||||
func Int() int { return globalRand.Int() }
|
||||
|
||||
// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n)
|
||||
// from the default Source.
|
||||
// It panics if n <= 0.
|
||||
func Int63n(n int64) int64 { return globalRand.Int63n(n) }
|
||||
|
||||
// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n)
|
||||
// from the default Source.
|
||||
// It panics if n <= 0.
|
||||
func Int31n(n int32) int32 { return globalRand.Int31n(n) }
|
||||
|
||||
// Intn returns, as an int, a non-negative pseudo-random number in [0,n)
|
||||
// from the default Source.
|
||||
// It panics if n <= 0.
|
||||
func Intn(n int) int { return globalRand.Intn(n) }
|
||||
|
||||
// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0)
|
||||
// from the default Source.
|
||||
func Float64() float64 { return globalRand.Float64() }
|
||||
|
||||
// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0)
|
||||
// from the default Source.
|
||||
func Float32() float32 { return globalRand.Float32() }
|
||||
|
||||
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n)
|
||||
// from the default Source.
|
||||
func Perm(n int) []int { return globalRand.Perm(n) }
|
||||
|
||||
// Shuffle pseudo-randomizes the order of elements using the default Source.
|
||||
// n is the number of elements. Shuffle panics if n < 0.
|
||||
// swap swaps the elements with indexes i and j.
|
||||
func Shuffle(n int, swap func(i, j int)) { globalRand.Shuffle(n, swap) }
|
||||
|
||||
// Read generates len(p) random bytes from the default Source and
|
||||
// writes them into p. It always returns len(p) and a nil error.
|
||||
// Read, unlike the Rand.Read method, is safe for concurrent use.
|
||||
func Read(p []byte) (n int, err error) { return globalRand.Read(p) }
|
||||
|
||||
// NormFloat64 returns a normally distributed float64 in the range
|
||||
// [-math.MaxFloat64, +math.MaxFloat64] with
|
||||
// standard normal distribution (mean = 0, stddev = 1)
|
||||
// from the default Source.
|
||||
// To produce a different normal distribution, callers can
|
||||
// adjust the output using:
|
||||
//
|
||||
// sample = NormFloat64() * desiredStdDev + desiredMean
|
||||
func NormFloat64() float64 { return globalRand.NormFloat64() }
|
||||
|
||||
// ExpFloat64 returns an exponentially distributed float64 in the range
|
||||
// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
|
||||
// (lambda) is 1 and whose mean is 1/lambda (1) from the default Source.
|
||||
// To produce a distribution with a different rate parameter,
|
||||
// callers can adjust the output using:
|
||||
//
|
||||
// sample = ExpFloat64() / desiredRateParameter
|
||||
func ExpFloat64() float64 { return globalRand.ExpFloat64() }
|
||||
|
||||
// LockedSource is an implementation of Source that is concurrency-safe.
|
||||
// A Rand using a LockedSource is safe for concurrent use.
|
||||
//
|
||||
// The zero value of LockedSource is valid, but should be seeded before use.
|
||||
type LockedSource struct {
|
||||
lk sync.Mutex
|
||||
src PCGSource
|
||||
}
|
||||
|
||||
func (s *LockedSource) Uint64() (n uint64) {
|
||||
s.lk.Lock()
|
||||
n = s.src.Uint64()
|
||||
s.lk.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
func (s *LockedSource) Seed(seed uint64) {
|
||||
s.lk.Lock()
|
||||
s.src.Seed(seed)
|
||||
s.lk.Unlock()
|
||||
}
|
||||
|
||||
// seedPos implements Seed for a LockedSource without a race condition.
|
||||
func (s *LockedSource) seedPos(seed uint64, readPos *int8) {
|
||||
s.lk.Lock()
|
||||
s.src.Seed(seed)
|
||||
*readPos = 0
|
||||
s.lk.Unlock()
|
||||
}
|
||||
|
||||
// Read implements Read for a LockedSource.
|
||||
func (s *LockedSource) Read(p []byte, readVal *uint64, readPos *int8) (n int, err error) {
|
||||
s.lk.Lock()
|
||||
n, err = read(p, &s.src, readVal, readPos)
|
||||
s.lk.Unlock()
|
||||
return
|
||||
}
|
||||
93
server/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/rng.go
generated
vendored
Normal file
93
server/vendor/go.mongodb.org/mongo-driver/v2/internal/rand/rng.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copied from https://cs.opensource.google/go/x/exp/+/24438e51023af3bfc1db8aed43c1342817e8cfcd:rand/rng.go
|
||||
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package rand
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
// PCGSource is an implementation of a 64-bit permuted congruential
|
||||
// generator as defined in
|
||||
//
|
||||
// PCG: A Family of Simple Fast Space-Efficient Statistically Good
|
||||
// Algorithms for Random Number Generation
|
||||
// Melissa E. O’Neill, Harvey Mudd College
|
||||
// http://www.pcg-random.org/pdf/toms-oneill-pcg-family-v1.02.pdf
|
||||
//
|
||||
// The generator here is the congruential generator PCG XSL RR 128/64 (LCG)
|
||||
// as found in the software available at http://www.pcg-random.org/.
|
||||
// It has period 2^128 with 128 bits of state, producing 64-bit values.
|
||||
// Is state is represented by two uint64 words.
|
||||
type PCGSource struct {
|
||||
low uint64
|
||||
high uint64
|
||||
}
|
||||
|
||||
const (
|
||||
maxUint32 = (1 << 32) - 1
|
||||
|
||||
multiplier = 47026247687942121848144207491837523525
|
||||
mulHigh = multiplier >> 64
|
||||
mulLow = multiplier & maxUint64
|
||||
|
||||
increment = 117397592171526113268558934119004209487
|
||||
incHigh = increment >> 64
|
||||
incLow = increment & maxUint64
|
||||
|
||||
// TODO: Use these?
|
||||
initializer = 245720598905631564143578724636268694099
|
||||
initHigh = initializer >> 64
|
||||
initLow = initializer & maxUint64
|
||||
)
|
||||
|
||||
// Seed uses the provided seed value to initialize the generator to a deterministic state.
|
||||
func (pcg *PCGSource) Seed(seed uint64) {
|
||||
pcg.low = seed
|
||||
pcg.high = seed // TODO: What is right?
|
||||
}
|
||||
|
||||
// Uint64 returns a pseudo-random 64-bit unsigned integer as a uint64.
|
||||
func (pcg *PCGSource) Uint64() uint64 {
|
||||
pcg.multiply()
|
||||
pcg.add()
|
||||
// XOR high and low 64 bits together and rotate right by high 6 bits of state.
|
||||
return bits.RotateLeft64(pcg.high^pcg.low, -int(pcg.high>>58))
|
||||
}
|
||||
|
||||
func (pcg *PCGSource) add() {
|
||||
var carry uint64
|
||||
pcg.low, carry = Add64(pcg.low, incLow, 0)
|
||||
pcg.high, _ = Add64(pcg.high, incHigh, carry)
|
||||
}
|
||||
|
||||
func (pcg *PCGSource) multiply() {
|
||||
hi, lo := Mul64(pcg.low, mulLow)
|
||||
hi += pcg.high * mulLow
|
||||
hi += pcg.low * mulHigh
|
||||
pcg.low = lo
|
||||
pcg.high = hi
|
||||
}
|
||||
|
||||
// MarshalBinary returns the binary representation of the current state of the generator.
|
||||
func (pcg *PCGSource) MarshalBinary() ([]byte, error) {
|
||||
var buf [16]byte
|
||||
binary.BigEndian.PutUint64(buf[:8], pcg.high)
|
||||
binary.BigEndian.PutUint64(buf[8:], pcg.low)
|
||||
return buf[:], nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary sets the state of the generator to the state represented in data.
|
||||
func (pcg *PCGSource) UnmarshalBinary(data []byte) error {
|
||||
if len(data) < 16 {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
pcg.low = binary.BigEndian.Uint64(data[8:])
|
||||
pcg.high = binary.BigEndian.Uint64(data[:8])
|
||||
return nil
|
||||
}
|
||||
39
server/vendor/go.mongodb.org/mongo-driver/v2/internal/randutil/randutil.go
generated
vendored
Normal file
39
server/vendor/go.mongodb.org/mongo-driver/v2/internal/randutil/randutil.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) MongoDB, Inc. 2022-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// Package randutil provides common random number utilities.
|
||||
package randutil
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
xrand "go.mongodb.org/mongo-driver/v2/internal/rand"
|
||||
)
|
||||
|
||||
// NewLockedRand returns a new "x/exp/rand" pseudo-random number generator seeded with a
|
||||
// cryptographically-secure random number.
|
||||
// It is safe to use from multiple goroutines.
|
||||
func NewLockedRand() *xrand.Rand {
|
||||
randSrc := new(xrand.LockedSource)
|
||||
randSrc.Seed(cryptoSeed())
|
||||
return xrand.New(randSrc)
|
||||
}
|
||||
|
||||
// cryptoSeed returns a random uint64 read from the "crypto/rand" random number generator. It is
|
||||
// intended to be used to seed pseudorandom number generators at package initialization. It panics
|
||||
// if it encounters any errors.
|
||||
func cryptoSeed() uint64 {
|
||||
var b [8]byte
|
||||
_, err := io.ReadFull(crand.Reader, b[:])
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to read 8 bytes from a \"crypto/rand\".Reader: %v", err))
|
||||
}
|
||||
|
||||
return (uint64(b[0]) << 0) | (uint64(b[1]) << 8) | (uint64(b[2]) << 16) | (uint64(b[3]) << 24) |
|
||||
(uint64(b[4]) << 32) | (uint64(b[5]) << 40) | (uint64(b[6]) << 48) | (uint64(b[7]) << 56)
|
||||
}
|
||||
359
server/vendor/go.mongodb.org/mongo-driver/v2/internal/serverselector/server_selector.go
generated
vendored
Normal file
359
server/vendor/go.mongodb.org/mongo-driver/v2/internal/serverselector/server_selector.go
generated
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
// Copyright (C) MongoDB, Inc. 2024-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package serverselector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/mongo/readpref"
|
||||
"go.mongodb.org/mongo-driver/v2/tag"
|
||||
"go.mongodb.org/mongo-driver/v2/x/mongo/driver/description"
|
||||
)
|
||||
|
||||
// Composite combines multiple selectors into a single selector by applying them
|
||||
// in order to the candidates list.
|
||||
//
|
||||
// For example, if the initial candidates list is [s0, s1, s2, s3] and two
|
||||
// selectors are provided where the first matches s0 and s1 and the second
|
||||
// matches s1 and s2, the following would occur during server selection:
|
||||
//
|
||||
// 1. firstSelector([s0, s1, s2, s3]) -> [s0, s1]
|
||||
// 2. secondSelector([s0, s1]) -> [s1]
|
||||
//
|
||||
// The final list of candidates returned by the composite selector would be
|
||||
// [s1].
|
||||
type Composite struct {
|
||||
Selectors []description.ServerSelector
|
||||
}
|
||||
|
||||
var _ description.ServerSelector = &Composite{}
|
||||
|
||||
// SelectServer combines multiple selectors into a single selector.
|
||||
func (selector *Composite) SelectServer(
|
||||
topo description.Topology,
|
||||
candidates []description.Server,
|
||||
) ([]description.Server, error) {
|
||||
var err error
|
||||
for _, sel := range selector.Selectors {
|
||||
candidates, err = sel.SelectServer(topo, candidates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return candidates, nil
|
||||
}
|
||||
|
||||
// Latency creates a ServerSelector which selects servers based on their average
|
||||
// RTT values.
|
||||
type Latency struct {
|
||||
Latency time.Duration
|
||||
}
|
||||
|
||||
var _ description.ServerSelector = &Latency{}
|
||||
|
||||
// SelectServer selects servers based on average RTT.
|
||||
func (selector *Latency) SelectServer(
|
||||
topo description.Topology,
|
||||
candidates []description.Server,
|
||||
) ([]description.Server, error) {
|
||||
if selector.Latency < 0 {
|
||||
return candidates, nil
|
||||
}
|
||||
if topo.Kind == description.TopologyKindLoadBalanced {
|
||||
// In LoadBalanced mode, there should only be one server in the topology and
|
||||
// it must be selected.
|
||||
return candidates, nil
|
||||
}
|
||||
|
||||
switch len(candidates) {
|
||||
case 0, 1:
|
||||
return candidates, nil
|
||||
default:
|
||||
min := time.Duration(math.MaxInt64)
|
||||
for _, candidate := range candidates {
|
||||
if candidate.AverageRTTSet {
|
||||
if candidate.AverageRTT < min {
|
||||
min = candidate.AverageRTT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if min == math.MaxInt64 {
|
||||
return candidates, nil
|
||||
}
|
||||
|
||||
max := min + selector.Latency
|
||||
|
||||
viableIndexes := make([]int, 0, len(candidates))
|
||||
for i, candidate := range candidates {
|
||||
if candidate.AverageRTTSet {
|
||||
if candidate.AverageRTT <= max {
|
||||
viableIndexes = append(viableIndexes, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(viableIndexes) == len(candidates) {
|
||||
return candidates, nil
|
||||
}
|
||||
result := make([]description.Server, len(viableIndexes))
|
||||
for i, idx := range viableIndexes {
|
||||
result[i] = candidates[idx]
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ReadPref selects servers based on the provided read preference.
|
||||
type ReadPref struct {
|
||||
ReadPref *readpref.ReadPref
|
||||
IsOutputAggregate bool
|
||||
}
|
||||
|
||||
var _ description.ServerSelector = &ReadPref{}
|
||||
|
||||
// SelectServer selects servers based on read preference.
|
||||
func (selector *ReadPref) SelectServer(
|
||||
topo description.Topology,
|
||||
candidates []description.Server,
|
||||
) ([]description.Server, error) {
|
||||
if topo.Kind == description.TopologyKindLoadBalanced {
|
||||
// In LoadBalanced mode, there should only be one server in the topology and
|
||||
// it must be selected. We check this before checking MaxStaleness support
|
||||
// because there's no monitoring in this mode, so the candidate server
|
||||
// wouldn't have a wire version set, which would result in an error.
|
||||
return candidates, nil
|
||||
}
|
||||
|
||||
switch topo.Kind {
|
||||
case description.TopologyKindSingle:
|
||||
return candidates, nil
|
||||
case description.TopologyKindReplicaSetNoPrimary, description.TopologyKindReplicaSetWithPrimary:
|
||||
return selectForReplicaSet(selector.ReadPref, selector.IsOutputAggregate, topo, candidates)
|
||||
case description.TopologyKindSharded:
|
||||
return selectByKind(candidates, description.ServerKindMongos), nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Write selects all the writable servers.
|
||||
type Write struct{}
|
||||
|
||||
var _ description.ServerSelector = &Write{}
|
||||
|
||||
// SelectServer selects all writable servers.
|
||||
func (selector *Write) SelectServer(
|
||||
topo description.Topology,
|
||||
candidates []description.Server,
|
||||
) ([]description.Server, error) {
|
||||
switch topo.Kind {
|
||||
case description.TopologyKindSingle, description.TopologyKindLoadBalanced:
|
||||
return candidates, nil
|
||||
default:
|
||||
// Determine the capacity of the results slice.
|
||||
selected := 0
|
||||
for _, candidate := range candidates {
|
||||
switch candidate.Kind {
|
||||
case description.ServerKindMongos, description.ServerKindRSPrimary, description.ServerKindStandalone:
|
||||
selected++
|
||||
}
|
||||
}
|
||||
|
||||
// Append candidates to the results slice.
|
||||
result := make([]description.Server, 0, selected)
|
||||
for _, candidate := range candidates {
|
||||
switch candidate.Kind {
|
||||
case description.ServerKindMongos, description.ServerKindRSPrimary, description.ServerKindStandalone:
|
||||
result = append(result, candidate)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Func is a function that can be used as a ServerSelector.
|
||||
type Func func(description.Topology, []description.Server) ([]description.Server, error)
|
||||
|
||||
// SelectServer implements the ServerSelector interface.
|
||||
func (ssf Func) SelectServer(
|
||||
t description.Topology,
|
||||
s []description.Server,
|
||||
) ([]description.Server, error) {
|
||||
return ssf(t, s)
|
||||
}
|
||||
|
||||
func verifyMaxStaleness(rp *readpref.ReadPref, topo description.Topology) error {
|
||||
maxStaleness, set := rp.MaxStaleness()
|
||||
if !set {
|
||||
return nil
|
||||
}
|
||||
|
||||
if maxStaleness < 90*time.Second {
|
||||
return fmt.Errorf("max staleness (%s) must be greater than or equal to 90s", maxStaleness)
|
||||
}
|
||||
|
||||
if len(topo.Servers) < 1 {
|
||||
// Maybe we should return an error here instead?
|
||||
return nil
|
||||
}
|
||||
|
||||
// we'll assume all candidates have the same heartbeat interval.
|
||||
s := topo.Servers[0]
|
||||
idleWritePeriod := 10 * time.Second
|
||||
|
||||
if maxStaleness < s.HeartbeatInterval+idleWritePeriod {
|
||||
return fmt.Errorf(
|
||||
"max staleness (%s) must be greater than or equal to the heartbeat interval (%s) plus idle write period (%s)",
|
||||
maxStaleness, s.HeartbeatInterval, idleWritePeriod,
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func selectByKind(candidates []description.Server, kind description.ServerKind) []description.Server {
|
||||
// Record the indices of viable candidates first and then append those to the returned slice
|
||||
// to avoid appending costly Server structs directly as an optimization.
|
||||
viableIndexes := make([]int, 0, len(candidates))
|
||||
for i, s := range candidates {
|
||||
if s.Kind == kind {
|
||||
viableIndexes = append(viableIndexes, i)
|
||||
}
|
||||
}
|
||||
if len(viableIndexes) == len(candidates) {
|
||||
return candidates
|
||||
}
|
||||
result := make([]description.Server, len(viableIndexes))
|
||||
for i, idx := range viableIndexes {
|
||||
result[i] = candidates[idx]
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func selectSecondaries(rp *readpref.ReadPref, candidates []description.Server) []description.Server {
|
||||
secondaries := selectByKind(candidates, description.ServerKindRSSecondary)
|
||||
if len(secondaries) == 0 {
|
||||
return secondaries
|
||||
}
|
||||
if maxStaleness, set := rp.MaxStaleness(); set {
|
||||
primaries := selectByKind(candidates, description.ServerKindRSPrimary)
|
||||
if len(primaries) == 0 {
|
||||
baseTime := secondaries[0].LastWriteTime
|
||||
for i := 1; i < len(secondaries); i++ {
|
||||
if secondaries[i].LastWriteTime.After(baseTime) {
|
||||
baseTime = secondaries[i].LastWriteTime
|
||||
}
|
||||
}
|
||||
|
||||
var selected []description.Server
|
||||
for _, secondary := range secondaries {
|
||||
estimatedStaleness := baseTime.Sub(secondary.LastWriteTime) + secondary.HeartbeatInterval
|
||||
if estimatedStaleness <= maxStaleness {
|
||||
selected = append(selected, secondary)
|
||||
}
|
||||
}
|
||||
|
||||
return selected
|
||||
}
|
||||
|
||||
primary := primaries[0]
|
||||
|
||||
var selected []description.Server
|
||||
for _, secondary := range secondaries {
|
||||
estimatedStaleness := secondary.LastUpdateTime.Sub(secondary.LastWriteTime) -
|
||||
primary.LastUpdateTime.Sub(primary.LastWriteTime) + secondary.HeartbeatInterval
|
||||
if estimatedStaleness <= maxStaleness {
|
||||
selected = append(selected, secondary)
|
||||
}
|
||||
}
|
||||
return selected
|
||||
}
|
||||
|
||||
return secondaries
|
||||
}
|
||||
|
||||
func selectByTagSet(candidates []description.Server, tagSets []tag.Set) []description.Server {
|
||||
if len(tagSets) == 0 {
|
||||
return candidates
|
||||
}
|
||||
|
||||
for _, ts := range tagSets {
|
||||
// If this tag set is empty, we can take a fast path because the empty list
|
||||
// is a subset of all tag sets, so all candidate servers will be selected.
|
||||
if len(ts) == 0 {
|
||||
return candidates
|
||||
}
|
||||
|
||||
var results []description.Server
|
||||
for _, s := range candidates {
|
||||
// ts is non-empty, so only servers with a non-empty set of tags need to be checked.
|
||||
if len(s.Tags) > 0 && s.Tags.ContainsAll(ts) {
|
||||
results = append(results, s)
|
||||
}
|
||||
}
|
||||
|
||||
if len(results) > 0 {
|
||||
return results
|
||||
}
|
||||
}
|
||||
|
||||
return []description.Server{}
|
||||
}
|
||||
|
||||
func selectForReplicaSet(
|
||||
rp *readpref.ReadPref,
|
||||
isOutputAggregate bool,
|
||||
topo description.Topology,
|
||||
candidates []description.Server,
|
||||
) ([]description.Server, error) {
|
||||
if err := verifyMaxStaleness(rp, topo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If underlying operation is an aggregate with an output stage, only apply read preference
|
||||
// if all candidates are 5.0+. Otherwise, operate under primary read preference.
|
||||
if isOutputAggregate {
|
||||
for _, s := range candidates {
|
||||
if s.WireVersion.Max < 13 {
|
||||
return selectByKind(candidates, description.ServerKindRSPrimary), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch rp.Mode() {
|
||||
case readpref.PrimaryMode:
|
||||
return selectByKind(candidates, description.ServerKindRSPrimary), nil
|
||||
case readpref.PrimaryPreferredMode:
|
||||
selected := selectByKind(candidates, description.ServerKindRSPrimary)
|
||||
|
||||
if len(selected) == 0 {
|
||||
selected = selectSecondaries(rp, candidates)
|
||||
return selectByTagSet(selected, rp.TagSets()), nil
|
||||
}
|
||||
|
||||
return selected, nil
|
||||
case readpref.SecondaryPreferredMode:
|
||||
selected := selectSecondaries(rp, candidates)
|
||||
selected = selectByTagSet(selected, rp.TagSets())
|
||||
if len(selected) > 0 {
|
||||
return selected, nil
|
||||
}
|
||||
return selectByKind(candidates, description.ServerKindRSPrimary), nil
|
||||
case readpref.SecondaryMode:
|
||||
selected := selectSecondaries(rp, candidates)
|
||||
return selectByTagSet(selected, rp.TagSets()), nil
|
||||
case readpref.NearestMode:
|
||||
selected := selectByKind(candidates, description.ServerKindRSPrimary)
|
||||
selected = append(selected, selectSecondaries(rp, candidates)...)
|
||||
return selectByTagSet(selected, rp.TagSets()), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unsupported mode: %d", rp.Mode())
|
||||
}
|
||||
68
server/vendor/go.mongodb.org/mongo-driver/v2/internal/uuid/uuid.go
generated
vendored
Normal file
68
server/vendor/go.mongodb.org/mongo-driver/v2/internal/uuid/uuid.go
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"io"
|
||||
|
||||
"go.mongodb.org/mongo-driver/v2/internal/randutil"
|
||||
)
|
||||
|
||||
// UUID represents a UUID.
|
||||
type UUID [16]byte
|
||||
|
||||
// A source is a UUID generator that reads random values from a io.Reader.
|
||||
// It should be safe to use from multiple goroutines.
|
||||
type source struct {
|
||||
random io.Reader
|
||||
}
|
||||
|
||||
// new returns a random UUIDv4 with bytes read from the source's random number generator.
|
||||
func (s *source) new() (UUID, error) {
|
||||
var uuid UUID
|
||||
_, err := io.ReadFull(s.random, uuid[:])
|
||||
if err != nil {
|
||||
return UUID{}, err
|
||||
}
|
||||
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// newSource returns a source that uses a pseudo-random number generator in reandutil package.
|
||||
// It is intended to be used to initialize the package-global UUID generator.
|
||||
func newSource() *source {
|
||||
return &source{
|
||||
random: randutil.NewLockedRand(),
|
||||
}
|
||||
}
|
||||
|
||||
// globalSource is a package-global pseudo-random UUID generator.
|
||||
var globalSource = newSource()
|
||||
|
||||
// New returns a random UUIDv4. It uses a global pseudo-random number generator in randutil
|
||||
// at package initialization.
|
||||
//
|
||||
// New should not be used to generate cryptographically-secure random UUIDs.
|
||||
func New() (UUID, error) {
|
||||
return globalSource.new()
|
||||
}
|
||||
|
||||
func (uuid UUID) String() string {
|
||||
var str [36]byte
|
||||
hex.Encode(str[:], uuid[:4])
|
||||
str[8] = '-'
|
||||
hex.Encode(str[9:13], uuid[4:6])
|
||||
str[13] = '-'
|
||||
hex.Encode(str[14:18], uuid[6:8])
|
||||
str[18] = '-'
|
||||
hex.Encode(str[19:23], uuid[8:10])
|
||||
str[23] = '-'
|
||||
hex.Encode(str[24:], uuid[10:])
|
||||
return string(str[:])
|
||||
}
|
||||
Reference in New Issue
Block a user