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