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  }