package wrapper import ( "html/template" "log" "net" "net/http" "os" "strings" "golang-fave/engine/sessions" Templates "golang-fave/engine/wrapper/resources/templates" ) const C_AssetsVersion = "3" type handleRun func(e *Wrapper) bool type tmplDataSystem struct { PathIcoFav string PathSvgLogo string PathCssStyles string PathCssCpStyles string PathCssBootstrap string PathJsJquery string PathJsPopper string PathJsBootstrap string PathJsCpScripts string BlockModalSysMsg template.HTML } type tmplDataAll struct { System tmplDataSystem Data interface{} } type Wrapper struct { W *http.ResponseWriter R *http.Request VHost string Port string DirWww string DirVhostHome string RemoteIp string LoggerAcc *log.Logger LoggerErr *log.Logger Session *sessions.Session Debug bool } func (e *Wrapper) tmplGetSystemData() tmplDataSystem { version := "?v=" + C_AssetsVersion return tmplDataSystem{ PathIcoFav: e.R.URL.Scheme + "://" + e.R.Host + "/assets/sys/fave.ico" + version, PathSvgLogo: e.R.URL.Scheme + "://" + e.R.Host + "/assets/sys/logo.svg" + version, PathCssStyles: e.R.URL.Scheme + "://" + e.R.Host + "/assets/sys/styles.css" + version, PathCssCpStyles: e.R.URL.Scheme + "://" + e.R.Host + "/assets/cp/styles.css" + version, PathCssBootstrap: e.R.URL.Scheme + "://" + e.R.Host + "/assets/sys/bootstrap.css" + version, PathJsJquery: e.R.URL.Scheme + "://" + e.R.Host + "/assets/sys/jquery.js" + version, PathJsPopper: e.R.URL.Scheme + "://" + e.R.Host + "/assets/sys/popper.js" + version, PathJsBootstrap: e.R.URL.Scheme + "://" + e.R.Host + "/assets/sys/bootstrap.js" + version, PathJsCpScripts: e.R.URL.Scheme + "://" + e.R.Host + "/assets/cp/scripts.js" + version, BlockModalSysMsg: template.HTML(Templates.BlockModalSysMsg), } } func New(w *http.ResponseWriter, r *http.Request, vhost string, port string, wwwdir string, vhosthome string, debug bool) *Wrapper { return &Wrapper{ VHost: vhost, Port: port, DirWww: wwwdir, DirVhostHome: vhosthome, W: w, R: r, Debug: debug, } } func (e *Wrapper) Run(hRun handleRun) { // Populate some values e.RemoteIp = e.R.RemoteAddr // Create loggers e.LoggerAcc = log.New(os.Stdout, e.VHost+", ", log.LstdFlags) e.LoggerErr = log.New(os.Stdout, e.VHost+", ", log.LstdFlags) // Attach file for access log if !e.Debug { acclogfile, acclogfileerr := os.OpenFile(e.DirVhostHome+"/logs/access.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if acclogfileerr == nil { defer acclogfile.Close() e.LoggerAcc.SetOutput(acclogfile) } } // Attach file for access log if !e.Debug { errlogfile, errlogfileerr := os.OpenFile(e.DirVhostHome+"/logs/error.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if errlogfileerr == nil { defer errlogfile.Close() e.LoggerErr.SetOutput(errlogfile) } } // Fix remote IP if strings.ContainsRune(e.R.RemoteAddr, ':') { e.RemoteIp, _, _ = net.SplitHostPort(e.R.RemoteAddr) } // Redirect to main domain if e.redirectToMainDomain() { e.Log("301") return } // Static resource if e.staticResource() { e.Log("200") return } // Static file if e.staticFile() { e.Log("200") return } // Friendly search engine url if e.redirectSeoFix() { e.Log("301") return } // Create and load session e.Session = sessions.New(e.W, e.R, e.VHost, e.DirVhostHome, e.RemoteIp) e.Session.Load() // Set session vars if !e.Session.IsSetInt("UserId") { e.Session.SetInt("UserId", 0) } if !e.Session.IsSetBool("IsLogged") { e.Session.SetBool("IsLogged", false) } // Logic if hRun != nil { if hRun(e) { e.Log("200") e.Session.Save() return } } // Show default page if e.R.URL.Path == "/" { e.Log("200") e.printPageDefault() } else { e.LogError("404") e.printPage404() } } func (e *Wrapper) Log(value string) { e.LoggerAcc.Println("[ACC] [" + e.R.Method + "] [" + value + "] [" + e.RemoteIp + "] [" + e.R.URL.Scheme + "://" + e.R.Host + e.R.URL.RequestURI() + "] [" + e.R.Header.Get("User-Agent") + "]") } func (e *Wrapper) LogError(value string) { e.LoggerErr.Println("[ERR] [" + e.R.Method + "] [" + value + "] [" + e.RemoteIp + "] [" + e.R.URL.Scheme + "://" + e.R.Host + e.R.URL.RequestURI() + "] [" + e.R.Header.Get("User-Agent") + "]") } func (e *Wrapper) TmplFrontEnd(tname string, data interface{}) bool { tmpl, err := template.ParseFiles( e.DirVhostHome+"/template"+"/"+tname+".html", e.DirVhostHome+"/template"+"/header.html", e.DirVhostHome+"/template"+"/sidebar.html", e.DirVhostHome+"/template"+"/footer.html", ) if err != nil { e.printTmplPageError(err) return true } (*e.W).Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") tmpl.Execute(*e.W, tmplDataAll{ System: e.tmplGetSystemData(), Data: data, }) return true } func (e *Wrapper) TmplBackEnd(tcont []byte, data interface{}) bool { tmpl, err := template.New("template").Parse(string(tcont)) if err != nil { e.printTmplPageError(err) return true } (*e.W).Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") tmpl.Execute(*e.W, tmplDataAll{ System: e.tmplGetSystemData(), Data: data, }) return true }