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  }