Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/mcp/notify.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func streamLogsToSession(
if line == "" {
continue
}
//nolint:staticcheck // SA1019: deprecated per SEP-2577; no replacement in go-sdk v1.7.0
_ = session.Log(ctx, &sdkmcp.LoggingMessageParams{
Level: "info",
Logger: "devsy",
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ require (
k8s.io/klog/v2 v2.140.0
k8s.io/kube-aggregator v0.36.3
k8s.io/kubectl v0.36.3
k8s.io/streaming v0.36.3
k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3
mvdan.cc/sh/v3 v3.13.1
sigs.k8s.io/controller-runtime v0.24.1
Expand Down Expand Up @@ -319,7 +320,6 @@ require (
k8s.io/component-base v0.36.3 // indirect
k8s.io/kube-openapi v0.0.0-20260624041617-8f3fa4921821 // indirect
k8s.io/metrics v0.36.3 // indirect
k8s.io/streaming v0.36.3 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
Expand Down
3 changes: 3 additions & 0 deletions pkg/agent/inject.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type InjectOptions struct {
// Ctx is the context for the injection operation. Required.
Ctx context.Context
// Exec is the function used to execute commands on the remote machine. Required.
//nolint:staticcheck // SA1019: legacy shell injection path, retained until callers migrate to AgentDelivery
Exec inject.ExecFunc

// IsLocal indicates if the injection target is the local machine.
Expand Down Expand Up @@ -228,6 +229,7 @@ func injectAgent(ctx *injectContext) error {
binaryLoader := createBinaryLoader(ctx)
scriptParams := buildScriptParams(ctx)

//nolint:staticcheck // SA1019: legacy shell injection path, retained until callers migrate to AgentDelivery
wasExecuted, err := inject.Inject(inject.InjectOptions{
Ctx: opts.Ctx,
Exec: opts.Exec,
Expand Down Expand Up @@ -352,6 +354,7 @@ func (vc *versionChecker) buildExistsCheck(agentPath string) string {
agentPath, agentPath, vc.remoteVersion)
}

//nolint:staticcheck // SA1019: legacy shell injection path, retained until callers migrate
func (vc *versionChecker) detectRemoteAgentVersion(
ctx context.Context,
exec inject.ExecFunc,
Expand Down
2 changes: 1 addition & 1 deletion pkg/driver/kubernetes/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import (
"os"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/httpstream"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/remotecommand"
"k8s.io/streaming/pkg/httpstream"
)

type Client struct {
Expand Down
67 changes: 43 additions & 24 deletions pkg/ts/workspace_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,13 +326,14 @@ func (s *WorkspaceServer) gitCredentialsHandler(
return
}

// Build the reverse proxy with a custom Director.
proxy := httputil.NewSingleHostReverseProxy(parsedURL)
proxy.Director = func(req *http.Request) {
dest := *parsedURL
req.URL = &dest
req.Host = dest.Host
req.Header.Set("Authorization", "Bearer "+s.config.AccessKey)
proxy := &httputil.ReverseProxy{
Rewrite: func(pr *httputil.ProxyRequest) {
dest := *parsedURL
pr.Out.URL = &dest
pr.Out.Host = dest.Host
pr.Out.Header.Set("Authorization", "Bearer "+s.config.AccessKey)
addForwardedFor(pr)
},
}
proxy.Transport = transport
proxy.ServeHTTP(w, r)
Expand Down Expand Up @@ -368,13 +369,14 @@ func (s *WorkspaceServer) dockerCredentialsHandler(
return
}

// Build the reverse proxy with a custom Director.
proxy := httputil.NewSingleHostReverseProxy(parsedURL)
proxy.Director = func(req *http.Request) {
dest := *parsedURL
req.URL = &dest
req.Host = dest.Host
req.Header.Set("Authorization", "Bearer "+s.config.AccessKey)
proxy := &httputil.ReverseProxy{
Rewrite: func(pr *httputil.ProxyRequest) {
dest := *parsedURL
pr.Out.URL = &dest
pr.Out.Host = dest.Host
pr.Out.Header.Set("Authorization", "Bearer "+s.config.AccessKey)
addForwardedFor(pr)
},
}
proxy.Transport = transport
proxy.ServeHTTP(w, r)
Expand Down Expand Up @@ -411,16 +413,17 @@ func (s *WorkspaceServer) httpPortForwardHandler(w http.ResponseWriter, r *http.
parsedURL.Host = "127.0.0.1:" + targetPort
log.Debugf("httpPortForwardHandler: final target URL=%s", parsedURL.String())

// Build the reverse proxy with a custom Director.
proxy := httputil.NewSingleHostReverseProxy(parsedURL)
proxy.Director = func(req *http.Request) {
dest := *parsedURL
req.URL = &dest
req.Host = dest.Host
// Remove custom headers so they are not forwarded.
req.Header.Del("X-Loft-Forward-Port")
req.Header.Del("X-Loft-Forward-Url")
req.Header.Del("X-Loft-Forward-Authorization")
proxy := &httputil.ReverseProxy{
Rewrite: func(pr *httputil.ProxyRequest) {
dest := *parsedURL
pr.Out.URL = &dest
pr.Out.Host = dest.Host
// Remove custom headers so they are not forwarded.
pr.Out.Header.Del("X-Loft-Forward-Port")
pr.Out.Header.Del("X-Loft-Forward-Url")
pr.Out.Header.Del("X-Loft-Forward-Authorization")
addForwardedFor(pr)
},
}
proxy.Transport = http.DefaultTransport

Expand All @@ -432,6 +435,22 @@ func (s *WorkspaceServer) httpPortForwardHandler(w http.ResponseWriter, r *http.
proxy.ServeHTTP(w, r)
}

// addForwardedFor sets X-Forwarded-For on the outbound proxy request.
func addForwardedFor(pr *httputil.ProxyRequest) {
clientIP, _, err := net.SplitHostPort(pr.In.RemoteAddr)
if err != nil {
return
}
prior, ok := pr.In.Header["X-Forwarded-For"]
omit := ok && prior == nil
if len(prior) > 0 {
clientIP = strings.Join(prior, ", ") + ", " + clientIP
}
if !omit {
pr.Out.Header.Set("X-Forwarded-For", clientIP)
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// handleSSHConnections continuously accepts SSH connections and handles each one.
func (s *WorkspaceServer) handleSSHConnections(ctx context.Context, listener net.Listener) {
for {
Expand Down
Loading