github.com/newrelic/go-agent@v3.26.0+incompatible/internal/utilization/provider.go (about) 1 // Copyright 2020 New Relic Corporation. All rights reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package utilization 5 6 import ( 7 "fmt" 8 "strings" 9 "time" 10 ) 11 12 // Helper constants, functions, and types common to multiple providers are 13 // contained in this file. 14 15 // Constants from the spec. 16 const ( 17 maxFieldValueSize = 255 // The maximum value size, in bytes. 18 providerTimeout = 1 * time.Second // The maximum time a HTTP provider may block. 19 lookupAddrTimeout = 500 * time.Millisecond 20 ) 21 22 type validationError struct{ e error } 23 24 func (a validationError) Error() string { 25 return a.e.Error() 26 } 27 28 func isValidationError(e error) bool { 29 _, is := e.(validationError) 30 return is 31 } 32 33 // This function normalises string values per the utilization spec. 34 func normalizeValue(s string) (string, error) { 35 out := strings.TrimSpace(s) 36 37 bytes := []byte(out) 38 if len(bytes) > maxFieldValueSize { 39 return "", validationError{fmt.Errorf("response is too long: got %d; expected <=%d", len(bytes), maxFieldValueSize)} 40 } 41 42 for i, r := range out { 43 if !isAcceptableRune(r) { 44 return "", validationError{fmt.Errorf("bad character %x at position %d in response", r, i)} 45 } 46 } 47 48 return out, nil 49 } 50 51 func isAcceptableRune(r rune) bool { 52 switch r { 53 case 0xFFFD: 54 return false // invalid UTF-8 55 case '_', ' ', '/', '.', '-': 56 return true 57 default: 58 return r > 0x7f || // still allows some invalid UTF-8, but that's the spec. 59 ('0' <= r && r <= '9') || 60 ('a' <= r && r <= 'z') || 61 ('A' <= r && r <= 'Z') 62 } 63 }