69 lines
2.3 KiB
Go

// Package apptracking defines the transport and persistence limits shared by the
// public App tracking endpoint and statistics-service.
package apptracking
import (
"bytes"
"encoding/json"
"strings"
)
const (
// MaxBatchSize keeps one request bounded before gateway fans it into the
// statistics write transaction.
MaxBatchSize = 50
// MaxPropertiesBytes bounds the raw JSON value after surrounding whitespace
// is removed. The value is rejected instead of truncated because truncation
// can change JSON meaning or produce invalid JSON.
MaxPropertiesBytes = 4096
// Text limits are byte limits, not rune limits. They mirror the durable
// app_tracking_events columns and therefore apply identically at both service
// boundaries; an oversized client value must never be deferred to MySQL.
MaxAppCodeBytes = 32
MaxEventIDBytes = 160
MaxEventNameBytes = 96
MaxEventTypeBytes = 64
MaxScreenBytes = 128
MaxTargetTypeBytes = 64
MaxTargetIDBytes = 128
MaxDeviceIDBytes = 128
MaxSessionIDBytes = 160
MaxPlatformBytes = 32
MaxAppVersionBytes = 64
MaxLanguageBytes = 32
MaxTimezoneBytes = 64
MaxErrorCodeBytes = 64
)
// ValidBatchSize rejects both empty reports and reports large enough to hold a
// statistics transaction open for an unbounded period.
func ValidBatchSize(size int) bool {
return size > 0 && size <= MaxBatchSize
}
// NormalizeText removes transport-only surrounding whitespace and checks the
// encoded byte length. Oversized values return false and are never shortened:
// identifiers and error codes are facts whose suffix may be significant.
func NormalizeText(value string, maxBytes int) (string, bool) {
value = strings.TrimSpace(value)
if maxBytes > 0 && len(value) > maxBytes {
return "", false
}
return value, true
}
// NormalizeProperties returns a detached, trimmed JSON value. Empty and JSON
// null both mean no properties; non-empty values must satisfy the same byte and
// syntax contract in gateway and statistics-service.
func NormalizeProperties(raw json.RawMessage) (json.RawMessage, bool) {
trimmed := bytes.TrimSpace(raw)
if len(trimmed) == 0 || bytes.Equal(trimmed, []byte("null")) {
return nil, true
}
if len(trimmed) > MaxPropertiesBytes || !json.Valid(trimmed) {
return nil, false
}
return json.RawMessage(bytes.Clone(trimmed)), true
}