mirror of
https://github.com/alireza0/s-ui.git
synced 2026-10-21 19:32:45 +00:00
Re-sync core/protocol/* from upstream (they were verbatim copies), re-fork core/box.go onto the new upstream box.go, and adapt to changed APIs: - adapter.ConnectionTracker gained RoutedFlow; add no-op impls to both trackers - log.ObservableFactory gained AttachPlatformWriter; add no-op impl - box.Context now takes a CertificateProviderRegistry; wire one up with the origin_ca provider - box.go now depends on debug*.go; copy them from upstream - hysteria inbound moved QUIC option building into quic.go; copy it Deps: sing v0.9.0-beta.4, sing-quic v0.7.0-beta.4, sing-tun v0.9.0-beta.2. Runtime behaviour is not yet validated and config migration for options deprecated in 1.14 is not done, so this is not ready for main.
76 lines
2.2 KiB
Go
76 lines
2.2 KiB
Go
package core
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
"net/http/pprof"
|
|
"runtime"
|
|
"runtime/debug"
|
|
"strings"
|
|
|
|
"github.com/sagernet/sing-box/log"
|
|
"github.com/sagernet/sing-box/option"
|
|
"github.com/sagernet/sing/common/byteformats"
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
"github.com/sagernet/sing/common/json"
|
|
"github.com/sagernet/sing/common/json/badjson"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
func startDebugHTTPServer(options option.DebugOptions) (*http.Server, error) {
|
|
if options.Listen == "" {
|
|
return nil, nil
|
|
}
|
|
r := chi.NewMux()
|
|
r.Route("/debug", func(r chi.Router) {
|
|
r.Get("/gc", func(writer http.ResponseWriter, request *http.Request) {
|
|
writer.WriteHeader(http.StatusNoContent)
|
|
go debug.FreeOSMemory()
|
|
})
|
|
r.Get("/memory", func(writer http.ResponseWriter, request *http.Request) {
|
|
var memStats runtime.MemStats
|
|
runtime.ReadMemStats(&memStats)
|
|
|
|
var memObject badjson.JSONObject
|
|
memObject.Put("heap", byteformats.FormatMemoryBytes(memStats.HeapInuse))
|
|
memObject.Put("stack", byteformats.FormatMemoryBytes(memStats.StackInuse))
|
|
memObject.Put("idle", byteformats.FormatMemoryBytes(memStats.HeapIdle-memStats.HeapReleased))
|
|
memObject.Put("goroutines", runtime.NumGoroutine())
|
|
memObject.Put("rss", rusageMaxRSS())
|
|
|
|
encoder := json.NewEncoder(writer)
|
|
encoder.SetIndent("", " ")
|
|
encoder.Encode(&memObject)
|
|
})
|
|
r.Route("/pprof", func(r chi.Router) {
|
|
r.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
|
|
if !strings.HasSuffix(request.URL.Path, "/") {
|
|
http.Redirect(writer, request, request.URL.Path+"/", http.StatusMovedPermanently)
|
|
} else {
|
|
pprof.Index(writer, request)
|
|
}
|
|
})
|
|
r.HandleFunc("/*", pprof.Index)
|
|
r.HandleFunc("/cmdline", pprof.Cmdline)
|
|
r.HandleFunc("/profile", pprof.Profile)
|
|
r.HandleFunc("/symbol", pprof.Symbol)
|
|
r.HandleFunc("/trace", pprof.Trace)
|
|
})
|
|
})
|
|
server := &http.Server{
|
|
Addr: options.Listen,
|
|
Handler: r,
|
|
}
|
|
listener, err := net.Listen("tcp", options.Listen)
|
|
if err != nil {
|
|
return nil, E.Cause(err, "listen debug HTTP server")
|
|
}
|
|
go func() {
|
|
err := server.Serve(listener)
|
|
if err != nil && !E.IsClosed(err) {
|
|
log.Error(E.Cause(err, "serve debug HTTP server"))
|
|
}
|
|
}()
|
|
return server, nil
|
|
}
|