github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/hypervisor/metadatad/httpHandler.go (about) 1 package metadatad 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "net" 8 "net/http" 9 "sort" 10 "strings" 11 "time" 12 13 "github.com/Cloud-Foundations/Dominator/lib/json" 14 proto "github.com/Cloud-Foundations/Dominator/proto/hypervisor" 15 ) 16 17 func (s *server) computePaths() { 18 s.paths = make(map[string]struct{}) 19 for path := range s.infoHandlers { 20 s.paths[path] = struct{}{} 21 } 22 for path := range s.rawHandlers { 23 s.paths[path] = struct{}{} 24 } 25 } 26 27 func (s *server) ServeHTTP(w http.ResponseWriter, req *http.Request) { 28 hostname, _, err := net.SplitHostPort(req.RemoteAddr) 29 if err != nil { 30 fmt.Fprintln(w, err) 31 return 32 } 33 ipAddr := net.ParseIP(hostname) 34 s.manager.NotifyVmMetadataRequest(ipAddr, req.URL.Path) 35 vmInfo, err := s.manager.GetVmInfo(ipAddr) 36 if err != nil { 37 w.Header().Set("Content-Type", "text/plain; charset=utf-8") 38 w.WriteHeader(http.StatusNotFound) 39 return 40 } 41 if rawHandler, ok := s.rawHandlers[req.URL.Path]; ok { 42 rawHandler(w, ipAddr) 43 return 44 } 45 writer := bufio.NewWriter(w) 46 defer writer.Flush() 47 if infoHandler, ok := s.infoHandlers[req.URL.Path]; ok { 48 if err := infoHandler(writer, vmInfo); err != nil { 49 fmt.Fprintln(writer, err) 50 } 51 return 52 } 53 paths := make([]string, 0) 54 pathsSet := make(map[string]struct{}) 55 for path := range s.paths { 56 if strings.HasPrefix(path, req.URL.Path) { 57 splitPath := strings.Split(path[len(req.URL.Path):], "/") 58 result := splitPath[0] 59 if result == "" { 60 result = splitPath[1] 61 } 62 if _, ok := pathsSet[result]; !ok { 63 pathsSet[result] = struct{}{} 64 paths = append(paths, result) 65 } 66 } 67 } 68 if len(paths) < 1 { 69 w.Header().Set("Content-Type", "text/plain; charset=utf-8") 70 w.WriteHeader(http.StatusNotFound) 71 return 72 } 73 sort.Strings(paths) 74 for _, path := range paths { 75 fmt.Fprintln(writer, path) 76 } 77 } 78 79 func (s *server) showTime(writer io.Writer, vmInfo proto.VmInfo) error { 80 now := time.Now() 81 nano := now.UnixNano() - now.Unix()*1000000000 82 _, err := fmt.Fprintf(writer, "%d.%09d\n", now.Unix(), nano) 83 return err 84 } 85 86 func (s *server) showVM(writer io.Writer, vmInfo proto.VmInfo) error { 87 return json.WriteWithIndent(writer, " ", vmInfo) 88 } 89 90 func (s *server) showTrue(w http.ResponseWriter, ipAddr net.IP) { 91 w.Write([]byte("true\n")) 92 } 93 94 func (s *server) showUserData(w http.ResponseWriter, ipAddr net.IP) { 95 if file, err := s.manager.GetVmUserData(ipAddr); err != nil { 96 w.Header().Set("Content-Type", "text/plain; charset=utf-8") 97 w.WriteHeader(http.StatusNotFound) 98 } else { 99 defer file.Close() 100 writer := bufio.NewWriter(w) 101 defer writer.Flush() 102 io.Copy(writer, file) 103 } 104 }