MCPcopy Create free account
hub / github.com/coder/aibridge / newPassthroughRouter

Function newPassthroughRouter

passthrough.go:24–120  ·  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].

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

Source from the content-addressed store, hash-verified

22// newPassthroughRouter returns a simple reverse-proxy implementation which will be used when a route is not handled specifically
23// by a [intercept.Provider].
24func newPassthroughRouter(prov provider.Provider, logger slog.Logger, m *metrics.Metrics, tracer trace.Tracer) http.HandlerFunc {
25 return func(w http.ResponseWriter, r *http.Request) {
26 if m != nil {
27 m.PassthroughCount.WithLabelValues(prov.Name(), r.URL.Path, r.Method).Add(1)
28 }
29
30 ctx, span := tracer.Start(r.Context(), "Passthrough", trace.WithAttributes(
31 attribute.String(tracing.PassthroughURL, r.URL.String()),
32 attribute.String(tracing.PassthroughMethod, r.Method),
33 ))
34 defer span.End()
35
36 upURL, err := url.Parse(prov.BaseURL())
37 if err != nil {
38 logger.Warn(ctx, "failed to parse provider base URL", slog.Error(err))
39 http.Error(w, "request error", http.StatusBadGateway)
40 span.SetStatus(codes.Error, "failed to parse provider base URL: "+err.Error())
41 return
42 }
43
44 // Append the request path to the upstream base path.
45 reqPath, err := url.JoinPath(upURL.Path, r.URL.Path)
46 if err != nil {
47 logger.Warn(ctx, "failed to join upstream path", slog.Error(err), slog.F("upstream_path", upURL.Path), slog.F("request_path", r.URL.Path))
48 http.Error(w, "failed to join upstream path", http.StatusInternalServerError)
49 span.SetStatus(codes.Error, "failed to join upstream path: "+err.Error())
50 return
51 }
52 // Ensure leading slash, proxied requests should have absolute paths.
53 // JoinPath can return relative paths, eg. when upURL path is empty.
54 if len(reqPath) == 0 || reqPath[0] != '/' {
55 reqPath = "/" + reqPath
56 }
57
58 // Build a reverse proxy to the upstream.
59 proxy := &httputil.ReverseProxy{
60 Director: func(req *http.Request) {
61 // Set scheme/host to upstream.
62 req.URL.Scheme = upURL.Scheme
63 req.URL.Host = upURL.Host
64 req.URL.Path = reqPath
65 req.URL.RawPath = ""
66
67 // Preserve query string.
68 req.URL.RawQuery = r.URL.RawQuery
69
70 // Set Host header for upstream.
71 req.Host = upURL.Host
72 span.SetAttributes(attribute.String(tracing.PassthroughUpstreamURL, req.URL.String()))
73
74 // Copy headers from client.
75 req.Header = r.Header.Clone()
76
77 // Standard proxy headers.
78 host, _, herr := net.SplitHostPort(r.RemoteAddr)
79 if herr != nil {
80 host = r.RemoteAddr
81 }

Callers 2

NewRequestBridgeFunction · 0.85
TestPassthroughRoutesFunction · 0.85

Calls 10

NewPassthroughMiddlewareFunction · 0.92
StartMethod · 0.80
ParseMethod · 0.80
GetMethod · 0.80
ServeHTTPMethod · 0.80
NameMethod · 0.65
BaseURLMethod · 0.65
InjectAuthHeaderMethod · 0.65
APIDumpDirMethod · 0.65
ErrorMethod · 0.45

Tested by 1

TestPassthroughRoutesFunction · 0.68