cleanup: move init funcs to the top of the source (#4172)
This commit is contained in:
commit
d5a1cf6816
14 changed files with 203 additions and 201 deletions
|
@ -9,6 +9,13 @@ import (
|
|||
|
||||
var updater = health.NewStatusUpdater()
|
||||
|
||||
// init sets up the two endpoints to bring the service up and down
|
||||
func init() {
|
||||
health.Register("manual_http_status", updater)
|
||||
http.HandleFunc("/debug/health/down", DownHandler)
|
||||
http.HandleFunc("/debug/health/up", UpHandler)
|
||||
}
|
||||
|
||||
// DownHandler registers a manual_http_status that always returns an Error
|
||||
func DownHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodPost {
|
||||
|
@ -26,10 +33,3 @@ func UpHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
// init sets up the two endpoints to bring the service up and down
|
||||
func init() {
|
||||
health.Register("manual_http_status", updater)
|
||||
http.HandleFunc("/debug/health/down", DownHandler)
|
||||
http.HandleFunc("/debug/health/up", UpHandler)
|
||||
}
|
||||
|
|
|
@ -13,6 +13,12 @@ import (
|
|||
"github.com/distribution/distribution/v3/registry/api/errcode"
|
||||
)
|
||||
|
||||
// Registers global /debug/health api endpoint, creates default registry
|
||||
func init() {
|
||||
DefaultRegistry = NewRegistry()
|
||||
http.HandleFunc("/debug/health", StatusHandler)
|
||||
}
|
||||
|
||||
// A Registry is a collection of checks. Most applications will use the global
|
||||
// registry defined in DefaultRegistry. However, unit tests may need to create
|
||||
// separate registries to isolate themselves from other tests.
|
||||
|
@ -278,9 +284,3 @@ func statusResponse(w http.ResponseWriter, r *http.Request, status int, checks m
|
|||
dcontext.GetLogger(r.Context()).Errorf("error writing health status response body: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Registers global /debug/health api endpoint, creates default registry
|
||||
func init() {
|
||||
DefaultRegistry = NewRegistry()
|
||||
http.HandleFunc("/debug/health", StatusHandler)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,48 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
// Octet types from RFC 2616.
|
||||
type octetType byte
|
||||
|
||||
var octetTypes [256]octetType
|
||||
|
||||
const (
|
||||
isToken octetType = 1 << iota
|
||||
isSpace
|
||||
)
|
||||
|
||||
func init() {
|
||||
// OCTET = <any 8-bit sequence of data>
|
||||
// CHAR = <any US-ASCII character (octets 0 - 127)>
|
||||
// CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
||||
// CR = <US-ASCII CR, carriage return (13)>
|
||||
// LF = <US-ASCII LF, linefeed (10)>
|
||||
// SP = <US-ASCII SP, space (32)>
|
||||
// HT = <US-ASCII HT, horizontal-tab (9)>
|
||||
// <"> = <US-ASCII double-quote mark (34)>
|
||||
// CRLF = CR LF
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
// TEXT = <any OCTET except CTLs, but including LWS>
|
||||
// separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
|
||||
// | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
|
||||
// token = 1*<any CHAR except CTLs or separators>
|
||||
// qdtext = <any TEXT except <">>
|
||||
|
||||
for c := 0; c < 256; c++ {
|
||||
var t octetType
|
||||
isCtl := c <= 31 || c == 127
|
||||
isChar := 0 <= c && c <= 127
|
||||
isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c))
|
||||
if strings.ContainsRune(" \t\r\n", rune(c)) {
|
||||
t |= isSpace
|
||||
}
|
||||
if isChar && !isCtl && !isSeparator {
|
||||
t |= isToken
|
||||
}
|
||||
octetTypes[c] = t
|
||||
}
|
||||
}
|
||||
|
||||
// Challenge carries information from a WWW-Authenticate response header.
|
||||
// See RFC 2617.
|
||||
type Challenge struct {
|
||||
|
@ -86,48 +128,6 @@ func (m *simpleManager) AddResponse(resp *http.Response) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Octet types from RFC 2616.
|
||||
type octetType byte
|
||||
|
||||
var octetTypes [256]octetType
|
||||
|
||||
const (
|
||||
isToken octetType = 1 << iota
|
||||
isSpace
|
||||
)
|
||||
|
||||
func init() {
|
||||
// OCTET = <any 8-bit sequence of data>
|
||||
// CHAR = <any US-ASCII character (octets 0 - 127)>
|
||||
// CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
||||
// CR = <US-ASCII CR, carriage return (13)>
|
||||
// LF = <US-ASCII LF, linefeed (10)>
|
||||
// SP = <US-ASCII SP, space (32)>
|
||||
// HT = <US-ASCII HT, horizontal-tab (9)>
|
||||
// <"> = <US-ASCII double-quote mark (34)>
|
||||
// CRLF = CR LF
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
// TEXT = <any OCTET except CTLs, but including LWS>
|
||||
// separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
|
||||
// | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
|
||||
// token = 1*<any CHAR except CTLs or separators>
|
||||
// qdtext = <any TEXT except <">>
|
||||
|
||||
for c := 0; c < 256; c++ {
|
||||
var t octetType
|
||||
isCtl := c <= 31 || c == 127
|
||||
isChar := 0 <= c && c <= 127
|
||||
isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c))
|
||||
if strings.ContainsRune(" \t\r\n", rune(c)) {
|
||||
t |= isSpace
|
||||
}
|
||||
if isChar && !isCtl && !isSeparator {
|
||||
t |= isToken
|
||||
}
|
||||
octetTypes[c] = t
|
||||
}
|
||||
}
|
||||
|
||||
// ResponseChallenges returns a list of authorization challenges
|
||||
// for the given http Response. Challenges are only checked if
|
||||
// the response status code was a 401.
|
||||
|
|
|
@ -20,6 +20,57 @@ var (
|
|||
statusCounter = prometheus.NotificationsNamespace.NewLabeledCounter("status", "The number of status code", "code", "endpoint")
|
||||
)
|
||||
|
||||
// endpoints is global registry of endpoints used to report metrics to expvar
|
||||
var endpoints struct {
|
||||
registered []*Endpoint
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func init() {
|
||||
// NOTE(stevvooe): Setup registry metrics structure to report to expvar.
|
||||
// Ideally, we do more metrics through logging but we need some nice
|
||||
// realtime metrics for queue state for now.
|
||||
|
||||
registry := expvar.Get("registry")
|
||||
|
||||
if registry == nil {
|
||||
registry = expvar.NewMap("registry")
|
||||
}
|
||||
|
||||
var notifications expvar.Map
|
||||
notifications.Init()
|
||||
notifications.Set("endpoints", expvar.Func(func() interface{} {
|
||||
endpoints.mu.Lock()
|
||||
defer endpoints.mu.Unlock()
|
||||
|
||||
var names []interface{}
|
||||
for _, v := range endpoints.registered {
|
||||
var epjson struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
EndpointConfig
|
||||
|
||||
Metrics EndpointMetrics
|
||||
}
|
||||
|
||||
epjson.Name = v.Name()
|
||||
epjson.URL = v.URL()
|
||||
epjson.EndpointConfig = v.EndpointConfig
|
||||
|
||||
v.ReadMetrics(&epjson.Metrics)
|
||||
|
||||
names = append(names, epjson)
|
||||
}
|
||||
|
||||
return names
|
||||
}))
|
||||
|
||||
registry.(*expvar.Map).Set("notifications", ¬ifications)
|
||||
|
||||
// register prometheus metrics
|
||||
metrics.Register(prometheus.NotificationsNamespace)
|
||||
}
|
||||
|
||||
// EndpointMetrics track various actions taken by the endpoint, typically by
|
||||
// number of events. The goal of this to export it via expvar but we may find
|
||||
// some other future solution to be better.
|
||||
|
@ -123,12 +174,6 @@ func (eqc *endpointMetricsEventQueueListener) egress(event events.Event) {
|
|||
pendingGauge.WithValues(eqc.EndpointName).Dec(1)
|
||||
}
|
||||
|
||||
// endpoints is global registry of endpoints used to report metrics to expvar
|
||||
var endpoints struct {
|
||||
registered []*Endpoint
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// register places the endpoint into expvar so that stats are tracked.
|
||||
func register(e *Endpoint) {
|
||||
endpoints.mu.Lock()
|
||||
|
@ -136,48 +181,3 @@ func register(e *Endpoint) {
|
|||
|
||||
endpoints.registered = append(endpoints.registered, e)
|
||||
}
|
||||
|
||||
func init() {
|
||||
// NOTE(stevvooe): Setup registry metrics structure to report to expvar.
|
||||
// Ideally, we do more metrics through logging but we need some nice
|
||||
// realtime metrics for queue state for now.
|
||||
|
||||
registry := expvar.Get("registry")
|
||||
|
||||
if registry == nil {
|
||||
registry = expvar.NewMap("registry")
|
||||
}
|
||||
|
||||
var notifications expvar.Map
|
||||
notifications.Init()
|
||||
notifications.Set("endpoints", expvar.Func(func() interface{} {
|
||||
endpoints.mu.Lock()
|
||||
defer endpoints.mu.Unlock()
|
||||
|
||||
var names []interface{}
|
||||
for _, v := range endpoints.registered {
|
||||
var epjson struct {
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
EndpointConfig
|
||||
|
||||
Metrics EndpointMetrics
|
||||
}
|
||||
|
||||
epjson.Name = v.Name()
|
||||
epjson.URL = v.URL()
|
||||
epjson.EndpointConfig = v.EndpointConfig
|
||||
|
||||
v.ReadMetrics(&epjson.Metrics)
|
||||
|
||||
names = append(names, epjson)
|
||||
}
|
||||
|
||||
return names
|
||||
}))
|
||||
|
||||
registry.(*expvar.Map).Set("notifications", ¬ifications)
|
||||
|
||||
// register prometheus metrics
|
||||
metrics.Register(prometheus.NotificationsNamespace)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,16 @@ import (
|
|||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
var routeDescriptorsMap map[string]RouteDescriptor
|
||||
|
||||
func init() {
|
||||
routeDescriptorsMap = make(map[string]RouteDescriptor, len(routeDescriptors))
|
||||
|
||||
for _, descriptor := range routeDescriptors {
|
||||
routeDescriptorsMap[descriptor.Name] = descriptor
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
nameParameterDescriptor = ParameterDescriptor{
|
||||
Name: "name",
|
||||
|
@ -1600,13 +1610,3 @@ var routeDescriptors = []RouteDescriptor{
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
var routeDescriptorsMap map[string]RouteDescriptor
|
||||
|
||||
func init() {
|
||||
routeDescriptorsMap = make(map[string]RouteDescriptor, len(routeDescriptors))
|
||||
|
||||
for _, descriptor := range routeDescriptors {
|
||||
routeDescriptorsMap[descriptor.Name] = descriptor
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,16 @@ var (
|
|||
ErrAuthenticationFailure = errors.New("authentication failure")
|
||||
)
|
||||
|
||||
// InitFunc is the type of an AccessController factory function and is used
|
||||
// to register the constructor for different AccesController backends.
|
||||
type InitFunc func(options map[string]interface{}) (AccessController, error)
|
||||
|
||||
var accessControllers map[string]InitFunc
|
||||
|
||||
func init() {
|
||||
accessControllers = make(map[string]InitFunc)
|
||||
}
|
||||
|
||||
// UserInfo carries information about
|
||||
// an autenticated/authorized client.
|
||||
type UserInfo struct {
|
||||
|
@ -104,16 +114,6 @@ type CredentialAuthenticator interface {
|
|||
AuthenticateUser(username, password string) error
|
||||
}
|
||||
|
||||
// InitFunc is the type of an AccessController factory function and is used
|
||||
// to register the constructor for different AccesController backends.
|
||||
type InitFunc func(options map[string]interface{}) (AccessController, error)
|
||||
|
||||
var accessControllers map[string]InitFunc
|
||||
|
||||
func init() {
|
||||
accessControllers = make(map[string]InitFunc)
|
||||
}
|
||||
|
||||
// Register is used to register an InitFunc for
|
||||
// an AccessController backend with the given name.
|
||||
func Register(name string, initFunc InitFunc) error {
|
||||
|
|
|
@ -23,6 +23,12 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := auth.Register("htpasswd", auth.InitFunc(newAccessController)); err != nil {
|
||||
logrus.Errorf("failed to register htpasswd auth: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
type accessController struct {
|
||||
realm string
|
||||
path string
|
||||
|
@ -150,9 +156,3 @@ func createHtpasswdFile(path string) error {
|
|||
}).Warnf("htpasswd is missing, provisioning with default user")
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
if err := auth.Register("htpasswd", auth.InitFunc(newAccessController)); err != nil {
|
||||
logrus.Errorf("failed to register htpasswd auth: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,13 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// init registers the silly auth backend.
|
||||
func init() {
|
||||
if err := auth.Register("silly", auth.InitFunc(newAccessController)); err != nil {
|
||||
logrus.Errorf("failed to register silly auth: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// accessController provides a simple implementation of auth.AccessController
|
||||
// that simply checks for a non-empty Authorization header. It is useful for
|
||||
// demonstration and testing.
|
||||
|
@ -85,10 +92,3 @@ func (ch challenge) SetHeaders(r *http.Request, w http.ResponseWriter) {
|
|||
func (ch challenge) Error() string {
|
||||
return fmt.Sprintf("silly authentication challenge: %#v", ch)
|
||||
}
|
||||
|
||||
// init registers the silly auth backend.
|
||||
func init() {
|
||||
if err := auth.Register("silly", auth.InitFunc(newAccessController)); err != nil {
|
||||
logrus.Errorf("failed to register silly auth: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,13 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// init handles registering the token auth backend.
|
||||
func init() {
|
||||
if err := auth.Register("token", auth.InitFunc(newAccessController)); err != nil {
|
||||
logrus.Errorf("tailed to register token auth: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// accessSet maps a typed, named resource to
|
||||
// a set of actions requested or authorized.
|
||||
type accessSet map[auth.Resource]actionSet
|
||||
|
@ -337,10 +344,3 @@ func (ac *accessController) Authorized(req *http.Request, accessItems ...auth.Ac
|
|||
Resources: claims.resources(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// init handles registering the token auth backend.
|
||||
func init() {
|
||||
if err := auth.Register("token", auth.InitFunc(newAccessController)); err != nil {
|
||||
logrus.Errorf("tailed to register token auth: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,14 +20,20 @@ import (
|
|||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
var sbsMu sync.Mutex
|
||||
var randSource rand.Rand
|
||||
var (
|
||||
sbsMu sync.Mutex
|
||||
randSource rand.Rand
|
||||
)
|
||||
|
||||
type statsBlobStore struct {
|
||||
stats map[string]int
|
||||
blobs distribution.BlobStore
|
||||
}
|
||||
|
||||
func init() {
|
||||
randSource = *rand.New(rand.NewSource(42))
|
||||
}
|
||||
|
||||
func (sbs statsBlobStore) Put(ctx context.Context, mediaType string, p []byte) (distribution.Descriptor, error) {
|
||||
sbsMu.Lock()
|
||||
sbs.stats["put"]++
|
||||
|
@ -195,10 +201,6 @@ func makeBlob(size int) []byte {
|
|||
return blob
|
||||
}
|
||||
|
||||
func init() {
|
||||
randSource = *rand.New(rand.NewSource(42))
|
||||
}
|
||||
|
||||
func populate(t *testing.T, te *testEnv, blobCount, size, numUnique int) {
|
||||
var inRemote []distribution.Descriptor
|
||||
|
||||
|
|
|
@ -36,6 +36,34 @@ type proxyMetricsCollector struct {
|
|||
manifestMetrics Metrics
|
||||
}
|
||||
|
||||
// proxyMetrics tracks metrics about the proxy cache. This is
|
||||
// kept globally and made available via expvar.
|
||||
var proxyMetrics = &proxyMetricsCollector{}
|
||||
|
||||
func init() {
|
||||
registry := expvar.Get("registry")
|
||||
if registry == nil {
|
||||
registry = expvar.NewMap("registry")
|
||||
}
|
||||
|
||||
pm := registry.(*expvar.Map).Get("proxy")
|
||||
if pm == nil {
|
||||
pm = &expvar.Map{}
|
||||
pm.(*expvar.Map).Init()
|
||||
registry.(*expvar.Map).Set("proxy", pm)
|
||||
}
|
||||
|
||||
pm.(*expvar.Map).Set("blobs", expvar.Func(func() interface{} {
|
||||
return proxyMetrics.blobMetrics
|
||||
}))
|
||||
|
||||
pm.(*expvar.Map).Set("manifests", expvar.Func(func() interface{} {
|
||||
return proxyMetrics.manifestMetrics
|
||||
}))
|
||||
|
||||
metrics.Register(prometheus.ProxyNamespace)
|
||||
}
|
||||
|
||||
// BlobPull tracks metrics about blobs pulled into the cache
|
||||
func (pmc *proxyMetricsCollector) BlobPull(bytesPulled uint64) {
|
||||
atomic.AddUint64(&pmc.blobMetrics.Misses, 1)
|
||||
|
@ -83,31 +111,3 @@ func (pmc *proxyMetricsCollector) ManifestPush(bytesPushed uint64, isHit bool) {
|
|||
hits.WithValues("manifest").Inc(1)
|
||||
}
|
||||
}
|
||||
|
||||
// proxyMetrics tracks metrics about the proxy cache. This is
|
||||
// kept globally and made available via expvar.
|
||||
var proxyMetrics = &proxyMetricsCollector{}
|
||||
|
||||
func init() {
|
||||
registry := expvar.Get("registry")
|
||||
if registry == nil {
|
||||
registry = expvar.NewMap("registry")
|
||||
}
|
||||
|
||||
pm := registry.(*expvar.Map).Get("proxy")
|
||||
if pm == nil {
|
||||
pm = &expvar.Map{}
|
||||
pm.(*expvar.Map).Init()
|
||||
registry.(*expvar.Map).Set("proxy", pm)
|
||||
}
|
||||
|
||||
pm.(*expvar.Map).Set("blobs", expvar.Func(func() interface{} {
|
||||
return proxyMetrics.blobMetrics
|
||||
}))
|
||||
|
||||
pm.(*expvar.Map).Set("manifests", expvar.Func(func() interface{} {
|
||||
return proxyMetrics.manifestMetrics
|
||||
}))
|
||||
|
||||
metrics.Register(prometheus.ProxyNamespace)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,13 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// init registers the cloudfront layerHandler backend.
|
||||
func init() {
|
||||
if err := storagemiddleware.Register("cloudfront", newCloudFrontStorageMiddleware); err != nil {
|
||||
logrus.Errorf("failed to register cloudfront middleware: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// cloudFrontStorageMiddleware provides a simple implementation of layerHandler that
|
||||
// constructs temporary signed CloudFront URLs from the storagedriver layer URL,
|
||||
// then issues HTTP Temporary Redirects to this CloudFront content URL.
|
||||
|
@ -224,10 +231,3 @@ func (lh *cloudFrontStorageMiddleware) RedirectURL(r *http.Request, path string)
|
|||
}
|
||||
return cfURL, nil
|
||||
}
|
||||
|
||||
// init registers the cloudfront layerHandler backend.
|
||||
func init() {
|
||||
if err := storagemiddleware.Register("cloudfront", newCloudFrontStorageMiddleware); err != nil {
|
||||
logrus.Errorf("failed to register cloudfront middleware: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,12 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := storagemiddleware.Register("redirect", newRedirectStorageMiddleware); err != nil {
|
||||
logrus.Errorf("tailed to register redirect storage middleware: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
type redirectStorageMiddleware struct {
|
||||
storagedriver.StorageDriver
|
||||
scheme string
|
||||
|
@ -51,9 +57,3 @@ func (r *redirectStorageMiddleware) RedirectURL(_ *http.Request, urlPath string)
|
|||
u := &url.URL{Scheme: r.scheme, Host: r.host, Path: urlPath}
|
||||
return u.String(), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
if err := storagemiddleware.Register("redirect", newRedirectStorageMiddleware); err != nil {
|
||||
logrus.Errorf("tailed to register redirect storage middleware: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,14 @@ import (
|
|||
// Test hooks up gocheck into the "go test" runner.
|
||||
func Test(t *testing.T) { check.TestingT(t) }
|
||||
|
||||
// randomBytes pre-allocates all of the memory sizes needed for the test. If
|
||||
// anything panics while accessing randomBytes, just make this number bigger.
|
||||
var randomBytes = make([]byte, 128<<20)
|
||||
|
||||
func init() {
|
||||
_, _ = crand.Read(randomBytes) // always returns len(randomBytes) and nil error
|
||||
}
|
||||
|
||||
// RegisterSuite registers an in-process storage driver test suite with
|
||||
// the go test runner.
|
||||
func RegisterSuite(driverConstructor DriverConstructor, skipCheck SkipCheck) {
|
||||
|
@ -1343,14 +1351,6 @@ func randomFilename(length int64) string {
|
|||
return string(b)
|
||||
}
|
||||
|
||||
// randomBytes pre-allocates all of the memory sizes needed for the test. If
|
||||
// anything panics while accessing randomBytes, just make this number bigger.
|
||||
var randomBytes = make([]byte, 128<<20)
|
||||
|
||||
func init() {
|
||||
_, _ = crand.Read(randomBytes) // always returns len(randomBytes) and nil error
|
||||
}
|
||||
|
||||
func randomContents(length int64) []byte {
|
||||
return randomBytes[:length]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue