MCPcopy Index your code
hub / github.com/coder/coder / newPassthroughRouter

Function newPassthroughRouter

aibridge/passthrough.go:27–77  ·  view source on GitHub ↗

newPassthroughRouter returns a simple reverse-proxy implementation which will be used when a route is not handled specifically by a [intercept.Provider]. A single reverse proxy is created per provider and reused across all requests.

(prov provider.Provider, logger slog.Logger, m *metrics.Metrics, tracer trace.Tracer)

Source from the content-addressed store, hash-verified

25// by a [intercept.Provider].
26// A single reverse proxy is created per provider and reused across all requests.
27func newPassthroughRouter(prov provider.Provider, logger slog.Logger, m *metrics.Metrics, tracer trace.Tracer) http.HandlerFunc {
28 provBaseURL, err := url.Parse(prov.BaseURL())
29 if err != nil {
30 return newInvalidBaseURLHandler(prov, logger, m, tracer, err)
31 }
32 if _, err := url.JoinPath(provBaseURL.Path, "/"); err != nil {
33 return newInvalidBaseURLHandler(prov, logger, m, tracer, err)
34 }
35
36 // Transport tuned for streaming (no response header timeout).
37 t := &http.Transport{
38 Proxy: http.ProxyFromEnvironment,
39 ForceAttemptHTTP2: true,
40 MaxIdleConns: 100,
41 IdleConnTimeout: 90 * time.Second,
42 TLSHandshakeTimeout: 10 * time.Second,
43 ExpectContinueTimeout: 1 * time.Second,
44 }
45
46 // Build the passthrough proxy, reused across all requests for this provider.
47 // Rewrite sets proxy headers. For centralized requests, KeyFailoverTransport
48 // handles auth and failover. BYOK requests pass through.
49 proxy := &httputil.ReverseProxy{
50 Rewrite: func(pr *httputil.ProxyRequest) {
51 rewritePassthroughRequest(pr, provBaseURL)
52 },
53 Transport: keypool.NewKeyFailoverTransport(
54 apidump.NewPassthroughMiddleware(t, prov.APIDumpDir(), prov.Name(), logger, quartz.NewReal()),
55 prov.KeyFailoverConfig(logger),
56 ),
57 ErrorHandler: func(rw http.ResponseWriter, req *http.Request, e error) {
58 if _, ok := errors.AsType[*http.MaxBytesError](e); ok {
59 writeRequestBodyTooLarge(rw)
60 } else {
61 logger.Warn(req.Context(), "reverse proxy error", slog.Error(e), slog.F("path", req.URL.Path))
62 http.Error(rw, "upstream proxy error", http.StatusBadGateway)
63 }
64 },
65 }
66
67 return func(w http.ResponseWriter, r *http.Request) {
68 if m != nil {
69 m.PassthroughCount.WithLabelValues(prov.Name(), r.URL.Path, r.Method).Add(1)
70 }
71
72 ctx, span := startSpan(r, tracer)
73 defer span.End()
74
75 proxy.ServeHTTP(w, r.WithContext(ctx))
76 }
77}
78
79// rewritePassthroughRequest configures the outbound request for the upstream and
80// applies proxy headers.

Callers 4

NewRequestBridgeFunction · 0.85
TestPassthroughRoutesFunction · 0.85

Calls 15

NewKeyFailoverTransportFunction · 0.92
NewPassthroughMiddlewareFunction · 0.92
newInvalidBaseURLHandlerFunction · 0.85
writeRequestBodyTooLargeFunction · 0.85
startSpanFunction · 0.85
WithLabelValuesMethod · 0.80
WithContextMethod · 0.80
ParseMethod · 0.65
BaseURLMethod · 0.65
APIDumpDirMethod · 0.65
NameMethod · 0.65

Tested by 3

TestPassthroughRoutesFunction · 0.68