()
| 23 | } |
| 24 | |
| 25 | func ExampleSnapshotHandler_complex() { |
| 26 | // This example does a few things: |
| 27 | // - Diables "augment" by default, can be enabled manually with "?augment=1". |
| 28 | // - Forces the "maxmem" value to reduce memory pressure in worst case. |
| 29 | // - Serializes handler to one at a time. |
| 30 | // - Throttles requests to once per second. |
| 31 | // - Limit request source IP to localhost and 100.64.x.x/10. (e.g. |
| 32 | // Tailscale). |
| 33 | |
| 34 | const delay = time.Second |
| 35 | mu := sync.Mutex{} |
| 36 | var last time.Time |
| 37 | http.HandleFunc("/debug/panicparse", func(w http.ResponseWriter, req *http.Request) { |
| 38 | // Only allow requests from localhost or in the 100.64.x.x/10 IPv4 range. |
| 39 | ok := false |
| 40 | if i := strings.LastIndexByte(req.RemoteAddr, ':'); i != -1 { |
| 41 | switch ip := req.RemoteAddr[:i]; ip { |
| 42 | case "localhost", "127.0.0.1", "[::1]", "::1": |
| 43 | ok = true |
| 44 | default: |
| 45 | p := net.ParseIP(ip).To4() |
| 46 | ok = p != nil && p[0] == 100 && p[1] >= 64 && p[1] < 128 |
| 47 | } |
| 48 | } |
| 49 | if !ok { |
| 50 | http.Error(w, "forbidden", http.StatusForbidden) |
| 51 | return |
| 52 | } |
| 53 | |
| 54 | // Serialize the handler. |
| 55 | mu.Lock() |
| 56 | defer mu.Unlock() |
| 57 | |
| 58 | // Throttle requests. |
| 59 | if time.Since(last) < delay { |
| 60 | http.Error(w, "retry later", http.StatusTooManyRequests) |
| 61 | return |
| 62 | } |
| 63 | |
| 64 | // Must be called before touching req.Form. |
| 65 | req.ParseForm() |
| 66 | // Disables source scanning by default since it's heavy. |
| 67 | if req.FormValue("augment") == "" { |
| 68 | req.Form.Set("augment", "0") |
| 69 | } |
| 70 | // Reduces maximum memory usage to 32MiB (from 64MiB) for the goroutines |
| 71 | // snapshot. |
| 72 | req.Form.Set("maxmem", "33554432") |
| 73 | |
| 74 | webstack.SnapshotHandler(w, req) |
| 75 | last = time.Now() |
| 76 | }) |
| 77 | |
| 78 | // Access as http://localhost:6060/debug/panicparse |
| 79 | log.Println(http.ListenAndServe("localhost:6060", nil)) |
| 80 | } |
nothing calls this directly
no test coverage detected
searching dependent graphs…