Use unique user in unknown command test to avoid last-command fallback interference. Add plugin architecture with registered commands. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
53 lines
1.7 KiB
Go
53 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"time"
|
|
)
|
|
|
|
type TracePlugin struct{}
|
|
|
|
func (p TracePlugin) Name() string { return "trace" }
|
|
func (p TracePlugin) ShortHelp() string { return "Time an HTTP request" }
|
|
func (p TracePlugin) DetailedHelp() string {
|
|
return "trace <url>\n\nTimes an HTTP/HTTPS request to the given URL and reports DNS lookup, connect, TLS negotiation, time to first byte, and time to last byte.\n\nExample:\n trace https://example.com"
|
|
}
|
|
func (p TracePlugin) Execute(msg BotMessage, args string) string {
|
|
uri, err := url.Parse(args)
|
|
if err != nil || (uri.Scheme != "http" && uri.Scheme != "https") {
|
|
return "That doesn't look like a valid URL for me to call"
|
|
}
|
|
|
|
response, err := timeRequest(msg.User.Name, uri)
|
|
if err != nil {
|
|
return "Failed to time the request"
|
|
}
|
|
return response
|
|
}
|
|
|
|
func timeRequest(username string, uri *url.URL) (string, error) {
|
|
trace, err := TraceRequest(uri)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
result := fmt.Sprintf("Hi %s! I've checked %s for you, and here's what I found:<br><br>\n", username, uri)
|
|
result += formatDuration("DNS lookup", trace.DNSStart, trace.DNSDone)
|
|
result += formatDuration("Connect", trace.ConnectStart, trace.ConnectDone)
|
|
result += formatDuration("TLS negotiation", trace.TLSStart, trace.TLSDone)
|
|
result += formatDuration("Sending headers", trace.ConnectionReady(), trace.WroteHeaders)
|
|
result += formatDuration("Time to first byte", trace.WroteHeaders, trace.FirstByte)
|
|
result += formatDuration("Time to last byte", trace.WroteHeaders, trace.AllDone)
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func formatDuration(label string, start, end time.Time) string {
|
|
dur := end.Sub(start).String()
|
|
if start.IsZero() || end.IsZero() {
|
|
dur = "n/a"
|
|
}
|
|
return fmt.Sprintf("%s: <strong>%s</strong><br>\n", label, dur)
|
|
}
|