package client import ( "encoding/json" "fmt" "io" "net" "net/http" "git.faercol.me/faercol/http-boot-server/bootserver/helpers" "git.faercol.me/faercol/http-boot-server/bootserver/services" "github.com/sirupsen/logrus" ) const BootRoute = "/boot" type BootController struct { clientService *services.ClientHandlerService l *logrus.Logger } func NewBootController(logger *logrus.Logger, service *services.ClientHandlerService) *BootController { return &BootController{ clientService: service, l: logger, } } func (bc *BootController) getBootOption(clientIP string, w http.ResponseWriter, r *http.Request) (int, []byte, error) { bootOption, err := bc.clientService.GetClientSelectedBootOption(clientIP) if err != nil { return http.StatusInternalServerError, nil, fmt.Errorf("failed to get boot option: %w", err) } dat, err := json.Marshal(bootOption) if err != nil { return http.StatusInternalServerError, nil, fmt.Errorf("failed to serialize body") } w.Header().Add("Content-Type", "application/json") return http.StatusOK, dat, nil } func (bc *BootController) setBootOption(clientIP string, w http.ResponseWriter, r *http.Request) (int, error) { dat, err := io.ReadAll(r.Body) if err != nil { return http.StatusInternalServerError, fmt.Errorf("failed to read body: %w", err) } var option string if err := json.Unmarshal(dat, &option); err != nil { return http.StatusInternalServerError, fmt.Errorf("failed to parse body: %w", err) } if err := bc.clientService.SetClientBootOption(clientIP, option); err != nil { return http.StatusInternalServerError, fmt.Errorf("failed to set boot option for client: %w", err) } return http.StatusAccepted, nil } func (bc *BootController) ServeHTTP(w http.ResponseWriter, r *http.Request) { clientIP, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { bc.l.Errorf("Failed to read remote IP: %s", err.Error()) helpers.HandleResponse(w, r, http.StatusInternalServerError, nil, bc.l) return } var returncode int var content []byte switch r.Method { case http.MethodGet: returncode, content, err = bc.getBootOption(clientIP, w, r) case http.MethodPut: returncode, err = bc.setBootOption(clientIP, w, r) default: returncode = http.StatusMethodNotAllowed } if err != nil { bc.l.Errorf("An error occured while handling boot request: %q", err.Error()) } helpers.HandleResponse(w, r, returncode, content, bc.l) }