// // rhctl // // Copyright (C) 2009-2016 Christian Pointner // // This file is part of rhctl. // // rhctl is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // // rhctl is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with rhctl. If not, see . // package main import ( "encoding/json" "fmt" "net/http" "time" ) type WebInterface struct { server *http.Server } type webHandler struct { ctrl *SwitchControl H func(*SwitchControl, http.ResponseWriter, *http.Request) } func (self webHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { self.H(self.ctrl, w, r) } func webSendResponse(w http.ResponseWriter, status int, respdata interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) encoder := json.NewEncoder(w) encoder.Encode(respdata) } type webError struct { ResponseCode int `json:"RESPONSE_CODE"` ErrorString string `json:"ERROR_STRING"` } func webSendErrorResponse(w http.ResponseWriter, status int, error string) { webSendResponse(w, http.StatusOK, webError{ResponseCode: status, ErrorString: error}) } func webGetStateHandler(ctrl *SwitchControl, w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { webSendErrorResponse(w, http.StatusMethodNotAllowed, "only GET method is allowed") return } resp := make(chan interface{}) ctrl.Commands <- &Command{Type: CmdState, Response: resp} result := <-resp switch result.(type) { case State: webSendResponse(w, http.StatusOK, result.(State)) case error: webSendErrorResponse(w, http.StatusInternalServerError, result.(error).Error()) default: webSendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("invalid response of type %T: %+v", result, result)) } } func (web *WebInterface) Run() { rhdl.Printf("Web: handler running...") if err := web.server.ListenAndServe(); err != nil { rhl.Printf("Web: server returned: %s", err) } } func WebInit(conf *Config, ctrl *SwitchControl) (web *WebInterface) { web = &WebInterface{} if conf.Clients.Web.StaticDir != "" { rhdl.Printf("Web: will serving static files from '%s'", conf.Clients.Web.StaticDir) http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(conf.Clients.Web.StaticDir)))) } http.Handle("/socket", webHandler{ctrl, webSocketHandler}) http.Handle("/api/state", webHandler{ctrl, webGetStateHandler}) // TODO: add other handler web.server = &http.Server{Addr: conf.Clients.Web.Address, ReadTimeout: 2 * time.Hour, WriteTimeout: 2 * time.Hour} return }