opencode-cursor-agent/internal/server/session.go

45 lines
1.2 KiB
Go
Raw Permalink Normal View History

2026-04-18 14:08:01 +00:00
package server
import (
2026-04-25 13:18:22 +00:00
"context"
2026-04-18 14:08:01 +00:00
"fmt"
"net/http"
2026-04-25 13:18:22 +00:00
"path/filepath"
2026-04-18 14:08:01 +00:00
"strings"
"time"
2026-04-25 13:18:22 +00:00
"github.com/daniel/cursor-adapter/internal/bridge"
2026-04-18 14:08:01 +00:00
)
const sessionHeaderName = "X-Cursor-Session-ID"
2026-04-25 13:18:22 +00:00
const workspaceHeaderName = "X-Cursor-Workspace"
2026-04-18 14:08:01 +00:00
const exposeHeadersName = "Access-Control-Expose-Headers"
2026-04-25 13:18:22 +00:00
// requestContext attaches per-request bridge knobs (currently: workspace
// override) read from headers onto ctx.
func requestContext(r *http.Request) context.Context {
ctx := r.Context()
ws := strings.TrimSpace(r.Header.Get(workspaceHeaderName))
if ws != "" && filepath.IsAbs(ws) {
ctx = bridge.WithWorkspaceOverride(ctx, ws)
}
return ctx
}
2026-04-18 14:08:01 +00:00
func ensureSessionHeader(w http.ResponseWriter, r *http.Request) string {
sessionKey := strings.TrimSpace(r.Header.Get(sessionHeaderName))
if sessionKey == "" {
sessionKey = fmt.Sprintf("csess_%d", time.Now().UnixNano())
}
w.Header().Set(sessionHeaderName, sessionKey)
existing := w.Header().Get(exposeHeadersName)
if existing == "" {
w.Header().Set(exposeHeadersName, sessionHeaderName)
} else if !strings.Contains(strings.ToLower(existing), strings.ToLower(sessionHeaderName)) {
w.Header().Set(exposeHeadersName, existing+", "+sessionHeaderName)
}
return sessionKey
}