1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- package utilization
- import (
- "fmt"
- "strings"
- "time"
- )
- // Helper constants, functions, and types common to multiple providers are
- // contained in this file.
- // Constants from the spec.
- const (
- maxFieldValueSize = 255 // The maximum value size, in bytes.
- providerTimeout = 1 * time.Second // The maximum time a HTTP provider may block.
- )
- type validationError struct{ e error }
- func (a validationError) Error() string {
- return a.e.Error()
- }
- func isValidationError(e error) bool {
- _, is := e.(validationError)
- return is
- }
- // This function normalises string values per the utilization spec.
- func normalizeValue(s string) (string, error) {
- out := strings.TrimSpace(s)
- bytes := []byte(out)
- if len(bytes) > maxFieldValueSize {
- return "", validationError{fmt.Errorf("response is too long: got %d; expected <=%d", len(bytes), maxFieldValueSize)}
- }
- for i, r := range out {
- if !isAcceptableRune(r) {
- return "", validationError{fmt.Errorf("bad character %x at position %d in response", r, i)}
- }
- }
- return out, nil
- }
- func isAcceptableRune(r rune) bool {
- switch r {
- case 0xFFFD:
- return false // invalid UTF-8
- case '_', ' ', '/', '.', '-':
- return true
- default:
- return r > 0x7f || // still allows some invalid UTF-8, but that's the spec.
- ('0' <= r && r <= '9') ||
- ('a' <= r && r <= 'z') ||
- ('A' <= r && r <= 'Z')
- }
- }
|