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  }