~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
162 lines · 4.2 KB Raw History
package ingress

import (
	"crypto/rand"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"strings"

	"github.com/gorilla/websocket"
	"github.com/johnandersen777/socialweb-computer-kcp/internal/kit/hostport"
)

const (
	SubscribeNSID    = "com.fedproxy.temp.xrpc.subscribe"
	GetNonceNSID     = "com.fedproxy.temp.xrpc.getRegistrationNonce"
	TunnelNSID       = "com.fedproxy.temp.xrpc.tunnel"
	RegistrationType = "com.fedproxy.temp.xrpc.registration"
	KeepalivePath    = "/xrpc/com.publicdomainrelay.temp.keepalive.ping"
	HealthPath       = "/xrpc/_health"
	DefaultServiceID = "xrpc_relay"

	MaxFrameBytes       = 64 << 20
	DefaultMaxBodyBytes = 32 << 20
	callerQueueDepth    = 4096
	maxCloseReasonBytes = 123
)

var relayedResponseHeaders = map[string]struct{}{
	"dpop-nonce":       {},
	"www-authenticate": {},
	"location":         {},
	"cache-control":    {},
	"retry-after":      {},
}

var subscriptionHeaders = []string{"authorization", "atproto-proxy"}

type Signature struct {
	Key       string `json:"key"`
	Signature string `json:"signature"`
}

type Registration struct {
	Type       string      `json:"$type"`
	Key        string      `json:"key"`
	Nonce      string      `json:"nonce"`
	Signatures []Signature `json:"signatures"`
}

type Request struct {
	RequestID string
	Method    string
	Path      string
	Params    map[string]string
	Body      json.RawMessage
	RawBody   string
	Headers   map[string]string
}

type Response struct {
	Status      int
	Body        json.RawMessage
	ContentType string
	Headers     map[string]string
}

type frame struct {
	Type           string            `json:"$type"`
	RequestID      string            `json:"requestId"`
	Method         string            `json:"method"`
	Path           string            `json:"path"`
	Params         map[string]string `json:"params"`
	Body           json.RawMessage   `json:"body"`
	RawBody        *string           `json:"rawBody"`
	Headers        map[string]string `json:"headers"`
	Status         int               `json:"status"`
	ContentType    string            `json:"contentType"`
	SubscriptionID string            `json:"subscriptionId"`
	NSID           string            `json:"nsid"`
	Message        json.RawMessage   `json:"message"`
	Data           string            `json:"data"`
	Code           int               `json:"code"`
	Reason         string            `json:"reason"`
	Key            string            `json:"key"`
	Nonce          string            `json:"nonce"`
	Signatures     []Signature       `json:"signatures"`
	Subdomain      string            `json:"subdomain"`
	IngressRef     string            `json:"ingressRef"`
}

func b64encode(b []byte) string {
	return base64.StdEncoding.EncodeToString(b)
}

func b64decode(s string) ([]byte, error) {
	return base64.StdEncoding.DecodeString(s)
}

func newID() string {
	b := make([]byte, 16)
	_, _ = rand.Read(b)
	return hex.EncodeToString(b)
}

func httpOrigin(host string, tls bool) string {
	if !tls && (strings.Contains(host, ":") || host == "localhost") {
		return "http://" + host
	}
	return "https://" + host
}

func wsOrigin(host string, tls bool) string {
	if !tls && (strings.Contains(host, ":") || host == "localhost") {
		return "ws://" + host
	}
	return "wss://" + host
}

func IngressURL(did, host string) string {
	return "https://" + hostport.DIDLabel(did) + "." + hostport.HostnameOnly(host)
}

func splitDataHost(host string, bases []string) (string, string, bool) {
	for _, base := range bases {
		if base == "" || base == "*" {
			continue
		}
		if before, ok := strings.CutSuffix(host, "."+base); ok {
			sub := before
			if sub == "" {
				continue
			}
			return base, sub, true
		}
	}
	return "", "", false
}

func closeFrame(code int, reason string) []byte {
	switch {
	case code >= 1000 && code <= 1003, code >= 1007 && code <= 1014, code >= 3000 && code <= 4999:
	default:
		code = 1000
	}
	if len(reason) > maxCloseReasonBytes {
		reason = reason[:maxCloseReasonBytes]
	}
	return websocket.FormatCloseMessage(code, reason)
}

func frameType(kind string) string {
	return SubscribeNSID + "#" + kind
}

func kindOf(typeName string) string {
	prefix := SubscribeNSID + "#"
	if !strings.HasPrefix(typeName, prefix) {
		return ""
	}
	return strings.TrimPrefix(typeName, prefix)
}