Skip to content

Commit 53dcbc9

Browse files
committed
feat(telegram): show HTTP version in per-request approval messages
Approval messages now display the negotiated HTTP version alongside the request method, e.g. "GET https://example.com/api (HTTP/2)". Helps distinguish HTTP/1.1 from HTTP/2 traffic in approval prompts.
1 parent 45643e3 commit 53dcbc9

5 files changed

Lines changed: 36 additions & 4 deletions

File tree

internal/channel/broker.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ func WithMethodAndPath(method, path string) RequestOption {
136136
}
137137
}
138138

139+
// WithHTTPVersion sets the negotiated HTTP version (e.g. "HTTP/2") for a
140+
// per-request approval so channels can display the protocol version.
141+
func WithHTTPVersion(version string) RequestOption {
142+
return func(c *requestConfig) {
143+
c.req.HTTPVersion = version
144+
}
145+
}
146+
139147
// WithBypassRateLimit tells the broker to skip the per-destination rate
140148
// limiter for this request. Per-request policy callers use this so a
141149
// keep-alive connection hammering a single destination does not silently

internal/channel/channel.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,11 @@ type ApprovalRequest struct {
7171
Method string
7272
// Path is the request URL path for per-request approvals (e.g. "/users/me").
7373
// Empty for connection-level approvals and non-HTTP protocols.
74-
Path string
75-
CreatedAt time.Time
74+
Path string
75+
// HTTPVersion is the negotiated HTTP version (e.g. "HTTP/1.1", "HTTP/2").
76+
// Empty for non-HTTP protocols.
77+
HTTPVersion string
78+
CreatedAt time.Time
7679
}
7780

7881
// Command represents an admin command received from a channel (e.g. Telegram

internal/proxy/addon.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,14 @@ func (a *SluiceAddon) Requestheaders(f *mitmproxy.Flow) {
424424
proto := a.detectRequestProtocol(f, connectPort)
425425
protoStr := proto.String()
426426

427+
httpVer := f.Request.Proto
428+
if httpVer == "" && f.ConnContext.ClientConn.NegotiatedProtocol == "h2" {
429+
httpVer = "HTTP/2"
430+
}
427431
verdict, err := checker.CheckAndConsume(connectHost, connectPort,
428432
WithRequestInfo(f.Request.Method, f.Request.URL.Path),
429433
WithProtocol(protoStr),
434+
WithHTTPVersion(httpVer),
430435
WithSkipBrokerRateLimit(),
431436
)
432437
if err != nil {

internal/proxy/request_policy.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ type checkContext struct {
214214
method string
215215
path string
216216
protocol string
217+
httpVersion string
217218
bypassRateLimit bool
218219
}
219220

@@ -246,6 +247,14 @@ func WithProtocol(proto string) CheckOption {
246247
}
247248
}
248249

250+
// WithHTTPVersion attaches the negotiated HTTP version (e.g. "HTTP/2") so
251+
// channels can display it alongside the request.
252+
func WithHTTPVersion(version string) CheckOption {
253+
return func(c *checkContext) {
254+
c.httpVersion = version
255+
}
256+
}
257+
249258
// WithSkipBrokerRateLimit signals that the broker should skip its per-
250259
// destination rate limiter for this approval request. Use this for
251260
// per-request policy callers so that a keep-alive connection to a single
@@ -281,6 +290,9 @@ func (c *RequestPolicyChecker) resolveAsk(dest string, port int, eng *policy.Eng
281290
if ctx.method != "" || ctx.path != "" {
282291
reqOpts = append(reqOpts, channel.WithMethodAndPath(ctx.method, ctx.path))
283292
}
293+
if ctx.httpVersion != "" {
294+
reqOpts = append(reqOpts, channel.WithHTTPVersion(ctx.httpVersion))
295+
}
284296
if ctx.bypassRateLimit {
285297
reqOpts = append(reqOpts, channel.WithBypassRateLimit())
286298
}

internal/telegram/bot.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,14 @@ func FormatApprovalMessage(req channel.ApprovalRequest) string {
7070
display = req.Protocol
7171
}
7272
if req.Method != "" {
73+
ver := ""
74+
if req.HTTPVersion != "" {
75+
ver = " (" + htmlEscape(req.HTTPVersion) + ")"
76+
}
7377
return fmt.Sprintf(
74-
"OpenClaw wants to connect to:\n\n%s %s:%d\n%s %s\n\nAllow this request?",
78+
"OpenClaw wants to connect to:\n\n%s %s:%d\n%s %s%s\n\nAllow this request?",
7579
htmlEscape(display), htmlEscape(req.Destination), req.Port,
76-
htmlEscape(req.Method), htmlEscape(buildRequestURL(req)),
80+
htmlEscape(req.Method), htmlEscape(buildRequestURL(req)), ver,
7781
)
7882
}
7983
return fmt.Sprintf(

0 commit comments

Comments
 (0)