45 lines
1.2 KiB
Go
45 lines
1.2 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/daniel/cursor-adapter/internal/bridge"
|
|
)
|
|
|
|
const sessionHeaderName = "X-Cursor-Session-ID"
|
|
const workspaceHeaderName = "X-Cursor-Workspace"
|
|
const exposeHeadersName = "Access-Control-Expose-Headers"
|
|
|
|
// 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
|
|
}
|
|
|
|
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
|
|
}
|