MCPcopy Create free account
hub / github.com/PostHog/duckgres / HandleProxy

Method HandleProxy

cmd/cache-proxy/proxy.go:256–353  ·  view source on GitHub ↗

HandleProxy handles forward HTTP proxy requests from DuckDB httpfs. Expects absolute-form URIs (scheme + host + path in the request-line).

(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

254 _ = upstream.Close()
255 _ = client.Close()
256 }()
257 go func() {
258 defer close(clientDone)
259 n, _ := io.Copy(client, upstream)
260 recvFromUpstream = n
261 _ = upstream.Close()
262 _ = client.Close()
263 }()
264
265 go func() {
266 <-upstreamDone
267 <-clientDone
268 span.SetAttributes(
269 attribute.Int64("duckgres.connect.sent_bytes", sentToUpstream),
270 attribute.Int64("duckgres.connect.recv_bytes", recvFromUpstream),
271 )
272 span.End()
273 slog.Info("Forward-proxy CONNECT closed.",
274 "target", target,
275 "sent_bytes", sentToUpstream,
276 "recv_bytes", recvFromUpstream,
277 "duration_ms", time.Since(connectStart).Milliseconds())
278 }()
279}
280
281// Hop-by-hop headers per RFC 7230 §6.1 — must not be forwarded.
282var hopByHop = map[string]bool{
283 "connection": true,
284 "keep-alive": true,
285 "proxy-authenticate": true,
286 "proxy-authorization": true,
287 "te": true,
288 "trailers": true,
289 "transfer-encoding": true,
290 "upgrade": true,
291}
292
293// cachePassthroughHeader is added only by duckgres's worker-local router.
294// It selects the proxy's observable-but-uncached request path and is stripped
295// before the origin request so it cannot affect S3 or a SigV4 request.
296const cachePassthroughHeader = "X-Duckgres-Cache-Passthrough"
297
298func isInternalPropagationHeader(header string) bool {
299 return strings.EqualFold(header, "traceparent") || strings.EqualFold(header, "tracestate")
300}
301
302// HandleProxy handles forward HTTP proxy requests from DuckDB httpfs.
303// Expects absolute-form URIs (scheme + host + path in the request-line).
304func (p *CacheProxy) HandleProxy(w http.ResponseWriter, r *http.Request) {
305 inflightRequests.Inc()
306 defer inflightRequests.Dec()
307 r = r.WithContext(otel.GetTextMapPropagator().Extract(r.Context(), propagation.HeaderCarrier(r.Header)))
308
309 // HTTPS via CONNECT tunnel — we can't cache encrypted traffic, but we must
310 // still tunnel it so DuckDB can reach external HTTPS sources (e.g.
311 // read_parquet('https://datasets.clickhouse.com/...')) while
312 // http_proxy is set globally.
313 if r.Method == http.MethodConnect {

Calls 15

handleConnectMethod · 0.95
forwardUncachedMethod · 0.95
shouldCacheMethod · 0.95
serveStreamMethod · 0.95
fetchDedupMethod · 0.95
writeToMethod · 0.95
CacheKeyFunction · 0.85
requestSpanAttrsFunction · 0.85
previewBodyFunction · 0.85
AddMethod · 0.80
openFileMethod · 0.80
CloseMethod · 0.65