69 lines
2.3 KiB
Go
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
|
|
}
|