github.com/Cloud-Foundations/Dominator@v0.3.4/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.fileHandlers { 20 s.paths[path] = struct{}{} 21 } 22 for path := range s.infoHandlers { 23 s.paths[path] = struct{}{} 24 } 25 for path := range s.rawHandlers { 26 s.paths[path] = struct{}{} 27 } 28 } 29 30 func (s *server) ServeHTTP(w http.ResponseWriter, req *http.Request) { 31 hostname, _, err := net.SplitHostPort(req.RemoteAddr) 32 if err != nil { 33 fmt.Fprintln(w, err) 34 return 35 } 36 ipAddr := net.ParseIP(hostname) 37 s.manager.NotifyVmMetadataRequest(ipAddr, req.URL.Path) 38 vmInfo, err := s.manager.GetVmInfo(ipAddr) 39 if err != nil { 40 w.Header().Set("Content-Type", "text/plain; charset=utf-8") 41 w.WriteHeader(http.StatusNotFound) 42 return 43 } 44 if filename, ok := s.fileHandlers[req.URL.Path]; ok { 45 s.showFileData(w, ipAddr, filename) 46 return 47 } 48 if rawHandler, ok := s.rawHandlers[req.URL.Path]; ok { 49 rawHandler(w, ipAddr) 50 return 51 } 52 writer := bufio.NewWriter(w) 53 defer writer.Flush() 54 if infoHandler, ok := s.infoHandlers[req.URL.Path]; ok { 55 if err := infoHandler(writer, vmInfo); err != nil { 56 fmt.Fprintln(writer, err) 57 } 58 return 59 } 60 paths := make([]string, 0) 61 pathsSet := make(map[string]struct{}) 62 for path := range s.paths { 63 result := "" 64 if strings.HasPrefix(path, req.URL.Path) { 65 splitPath := strings.Split(path[len(req.URL.Path):], "/") 66 result = splitPath[0] 67 if result == "" { 68 result = splitPath[1] 69 } 70 } else if req.URL.Path == "/*" { 71 result = path[1:] 72 } 73 if result != "" { 74 if _, ok := pathsSet[result]; !ok { 75 pathsSet[result] = struct{}{} 76 paths = append(paths, result) 77 } 78 } 79 } 80 if len(paths) < 1 { 81 w.Header().Set("Content-Type", "text/plain; charset=utf-8") 82 w.WriteHeader(http.StatusNotFound) 83 return 84 } 85 sort.Strings(paths) 86 for _, path := range paths { 87 fmt.Fprintln(writer, path) 88 } 89 } 90 91 func (s *server) showTime(writer io.Writer, vmInfo proto.VmInfo) error { 92 now := time.Now() 93 nano := now.UnixNano() - now.Unix()*1000000000 94 _, err := fmt.Fprintf(writer, "%d.%09d\n", now.Unix(), nano) 95 return err 96 } 97 98 func (s *server) showVM(writer io.Writer, vmInfo proto.VmInfo) error { 99 return json.WriteWithIndent(writer, " ", vmInfo) 100 } 101 102 func (s *server) showTrue(w http.ResponseWriter, ipAddr net.IP) { 103 w.Write([]byte("true\n")) 104 } 105 106 func (s *server) showFileData(w http.ResponseWriter, ipAddr net.IP, 107 filename string) { 108 if file, err := s.manager.GetVmFileData(ipAddr, filename); err != nil { 109 w.Header().Set("Content-Type", "text/plain; charset=utf-8") 110 w.WriteHeader(http.StatusNotFound) 111 } else { 112 defer file.Close() 113 writer := bufio.NewWriter(w) 114 defer writer.Flush() 115 io.Copy(writer, file) 116 } 117 }