// Copyright 2026 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT // Package sessiontag carries a per-page-load identifier from the // originating HTTP request down to the service- and model-layer SSE // publishers. The publishers echo the tag back inside event payloads so // the originating browser tab can suppress its own event after it has // already applied the optimistic update locally. // // It is deliberately tiny and dependency-free so any feature that emits // Server-Sent Events (project boards, milestones, ...) can share one // context key without importing one another. package sessiontag import "context" // sessionTagCtxKey is the context key under which the X-Session-Tag // value from the originating HTTP request is stashed. type sessionTagCtxKey struct{} // WithSessionTag returns ctx decorated with the provided session tag. // Web/API middleware reads the X-Session-Tag header and calls this so // service- and model-layer publishers can pull the tag back out. func WithSessionTag(ctx context.Context, tag string) context.Context { if tag == "" { return ctx } return context.WithValue(ctx, sessionTagCtxKey{}, tag) } // SessionTagFromContext returns the session tag previously stored via // WithSessionTag, or "" when none was set. func SessionTagFromContext(ctx context.Context) string { if v, ok := ctx.Value(sessionTagCtxKey{}).(string); ok { return v } return "" }