μν€ν μ²
μμ² νλ¦
μΉμ μ λͺ©: βμμ² νλ¦βAI CLI (claude-code, claude-cli, ...) β β HTTP to 127.0.0.1:3817 βΌβββββββββββββββββββββββββββββββββββββββββββββββββ sotatek-proxy (Gin engine, loopback bind) ββ ββ recoveryLogger panic recovery ββ requestLogger scrub Authorization, ββ x-api-key, drop query ββ MiddlewareGitRemote ββ β ββ ββ extract peer port from RemoteAddr ββ ββ inspect.GetPidByPeerPort β PID ββ ββ inspect.GetCwdByPid β CWD ββ ββ walk parents (β€3) for .git ββ ββ cache.Get(pid) [verify CWD] ββ ββ git.GetRemoteRaw(cwd) (2s timeout) ββ ββ inject X-Git-Remote (base64) ββ ββ ReverseProxy (NoRoute) ββ ββ stamp User-Agent: sotatek-proxy/X ββ ββ preserve original in ββ β X-Forwarded-User-Agent ββ ββ FlushInterval=-1 (SSE-safe) βββββββββββββββββββββββ¬ββββββββββββββββββββββββββ β HTTP/2 (ForceAttemptHTTP2) βΌ https://bifrost.sotatek.works/anthropic/v1/*λ―Έλ€μ¨μ΄ 체μΈ
μΉμ μ λͺ©: βλ―Έλ€μ¨μ΄ 체μΈβμμκ° μ€μν©λλ€. κ° λ μ΄μ΄λ μμ² μ μ΄ μμλ‘ μ€νλλ©°, μλ΅ μ μμμΌλ‘ μ€νλ©λλ€.
| # | λ―Έλ€μ¨μ΄ | λͺ©μ |
|---|---|---|
| 1 | recoveryLogger | ν¨λ 볡ꡬ; μμ² ν€λλ₯Ό μ λ μΆλ ₯νμ§ μμ΅λλ€. |
| 2 | requestLogger | μμ²λ³ κ°κ²°ν ꡬ쑰ν λ‘κ·Έ: λ©μλ, κ²½λ‘, μν, μ§μ° μκ°, client_ip, has_auth/has_api_key λΆλ¦¬μΈ, has_query νλκ·Έ. Authorization κ°μ μ λ κΈ°λ‘λμ§ μμ΅λλ€. |
| 3 | MiddlewareGitRemote | νΈμΆ PIDμ CWDλ₯Ό νμΈνκ³ , git remote -vλ₯Ό μ€ννλ©°, κ²°κ³Όλ₯Ό base64λ‘ μΈμ½λ©νμ¬ X-Git-Remoteλ₯Ό μ€μ ν©λλ€. ν΄λΌμ΄μΈνΈκ° μ 곡ν X-Git-Remoteλ λ¨Όμ μ κ±°λ©λλ€. |
| 4 | ReverseProxy (NoRoute) | μ
μ€νΈλ¦ΌμΌλ‘ 1:1 μ λ¬, User-Agent μ€ν¬ν, SSEλ₯Ό λ²νΌλ§ μμ΄ μ€νΈλ¦¬λ°ν©λλ€. |
νλ‘μΈμ€ κ²μ¬ (PID β CWD β git)
μΉμ μ λͺ©: βνλ‘μΈμ€ κ²μ¬ (PID β CWD β git)βνλ‘μλ ν΄λΌμ΄μΈνΈμ TCP νΌμ΄ ν¬νΈ (CLIκ° μ°κ²°μ μ¬μ©ν ν¬νΈ)λ₯Ό PIDλ‘, κ·Έλ€μ CWDλ‘ μμΆμ ν ν .gitμ μ°Ύμ μ΅λ 3κ°μ μμ λλ ν 리λ₯Ό νμν©λλ€.
| OS | ꡬν λ°©μ |
|---|---|
| macOS | lsof -iTCP:<port> -sTCP:ESTABLISHED -F pn (PID), lsof -p <pid> -d cwd -F n (CWD). 2μ΄ μ€ν νμμμ. |
| Linux | /proc/net/tcp[6]μ μ½μ΄ ν¬νΈ β μμ΄λ
Έλλ₯Ό λ§€ννκ³ , /proc/*/fd/μμ μΌμΉνλ μμΌμ μ€μΊν ν /proc/<pid>/cwdλ₯Ό μ½μ΅λλ€. λμΌ μ¬μ©μμκ²λ§ μ μ©λ©λλ€. |
| Windows | IPv4/IPv6 μ°κ²° ν
μ΄λΈμ μν GetExtendedTcpTable; CWDλ₯Ό μν NtQueryInformationProcessλ₯Ό ν΅ν PEB νμ. 64λΉνΈ μ μ©. |
μμ νμμ μΌλ°μ μΈ λνν μ
Έ (bash, zsh, fish, sh, dash, ksh, tcsh, csh)μμ μ€μ§λλ―λ‘ νλ‘μκ° μ
Έμ CWDλ₯Ό κ°λ‘μ±μ§ μμ΅λλ€.
PID β {cwd, git-remote} μΊμλ TTL(κΈ°λ³Έ 60μ΄)μ΄ μλ sync.Mapμ μ¬μ©ν©λλ€. Get νΈμΆ μλ§λ€ νμ¬ CWDλ₯Ό λ€μ μ½μΌλ©°, CWDκ° μΌμΉνμ§ μμΌλ©΄ μΊμ νλͺ©μ΄ μ κ±°λ©λλ€ β μ΄λ PID μ¬μ¬μ©μ λν λ°©μ΄ λ©μ»€λμ¦μ
λλ€.
λ°±κ·ΈλΌμ΄λ μ 리 μμ
μ΄ 5λΆλ§λ€ λ§λ£λ νλͺ©κ³Ό PIDκ° λ μ΄μ μ΄μμμ§ μμ νλͺ©(kill -0)μ μ κ±°ν©λλ€.
git remote -v μ
Έ μ€νμλ 2μ΄μ νλ νμμμμ΄ μμ΅λλ€. νμμμμ΄ λ°μνκ±°λ 리λͺ¨νΈκ° μλ κ²½μ° μμ²μ X-Git-Remote ν€λ μμ΄ μ λ¬λ©λλ€ β μ°¨λ¨λμ§ μμ΅λλ€.
μ€νΈλ¦¬λ°
μΉμ μ λͺ©: βμ€νΈλ¦¬λ°βνλ‘μλ FlushInterval=-1μ μ¬μ©νλ httputil.ReverseProxyλ₯Ό μ¬μ©νλ©°, μ΄λ μ°κΈ°λ§λ€ κ°μ νλ¬μλ₯Ό μνν©λλ€. SSE / μ²ν¬ μλ΅μ μ
μ€νΈλ¦Όμ΄ μ μ‘νλ μ¦μ ν΄λΌμ΄μΈνΈμ λλ¬ν©λλ€ β λ³Έλ¬Έ λ²νΌλ§ μμ. ν΄λΌμ΄μΈνΈ μ°κ²° ν΄μ μ μ
μ€νΈλ¦Ό 컨ν
μ€νΈκ° μ·¨μλ©λλ€.
ν¬μ€ μλν¬μΈνΈ
μΉμ μ λͺ©: βν¬μ€ μλν¬μΈνΈβGET /_proxy/healthzλ²μ , 컀λ°, μ νμ, (μ°κ²°λ κ²½μ°) μΊμ ν΅κ³λ₯Ό λ°νν©λλ€.
{ "status": "ok", "version": "v0.1.0", "commit": "abc1234", "uptime": "1h23m", "cache": { "entries": 12, "hits": 480, "misses": 64, "hit_rate": 0.882 }}