| // Copyright 2009 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package rpc | |
| /* | |
| Some HTML presented at http://machine:port/debug/rpc | |
| Lists services, their methods, and some statistics, still rudimentary. | |
| */ | |
| import ( | |
| "fmt" | |
| "html/template" | |
| "net/http" | |
| "sort" | |
| ) | |
| const debugText = `<html> | |
| <body> | |
| <title>Services</title> | |
| {{range .}} | |
| <hr> | |
| Service {{.Name}} | |
| <hr> | |
| <table> | |
| <th align=center>Method</th><th align=center>Calls</th> | |
| {{range .Method}} | |
| <tr> | |
| <td align=left font=fixed>{{.Name}}({{.Type.ArgType}}, {{.Type.ReplyType}}) error</td> | |
| <td align=center>{{.Type.NumCalls}}</td> | |
| </tr> | |
| {{end}} | |
| </table> | |
| {{end}} | |
| </body> | |
| </html>` | |
| var debug = template.Must(template.New("RPC debug").Parse(debugText)) | |
| // If set, print log statements for internal and I/O errors. | |
| var debugLog = false | |
| type debugMethod struct { | |
| Type *methodType | |
| Name string | |
| } | |
| type methodArray []debugMethod | |
| type debugService struct { | |
| Service *service | |
| Name string | |
| Method methodArray | |
| } | |
| type serviceArray []debugService | |
| func (s serviceArray) Len() int { return len(s) } | |
| func (s serviceArray) Less(i, j int) bool { return s[i].Name < s[j].Name } | |
| func (s serviceArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] } | |
| func (m methodArray) Len() int { return len(m) } | |
| func (m methodArray) Less(i, j int) bool { return m[i].Name < m[j].Name } | |
| func (m methodArray) Swap(i, j int) { m[i], m[j] = m[j], m[i] } | |
| type debugHTTP struct { | |
| *Server | |
| } | |
| // Runs at /debug/rpc | |
| func (server debugHTTP) ServeHTTP(w http.ResponseWriter, req *http.Request) { | |
| // Build a sorted version of the data. | |
| var services serviceArray | |
| server.serviceMap.Range(func(snamei, svci interface{}) bool { | |
| svc := svci.(*service) | |
| ds := debugService{svc, snamei.(string), make(methodArray, 0, len(svc.method))} | |
| for mname, method := range svc.method { | |
| ds.Method = append(ds.Method, debugMethod{method, mname}) | |
| } | |
| sort.Sort(ds.Method) | |
| services = append(services, ds) | |
| return true | |
| }) | |
| sort.Sort(services) | |
| err := debug.Execute(w, services) | |
| if err != nil { | |
| fmt.Fprintln(w, "rpc: error executing template:", err.Error()) | |
| } | |
| } |