func (s *SessionManager) Set(session map[string]interface{}, rw http.ResponseWriter, req *http.Request) { c, cerr := req.Cookie(s.CookieName) lsess := len(session) if cerr == nil { sessionSign := c.Value if lsess > 0 { if encodeSession, err := encodeGob(session); err == nil { writeFile(s.sessionDir+sessionSign+".golanger", encodeSession) } else { log.Error("<SessionManager.Set> ", "encodeGob:", err) } } else { s.Clear(sessionSign) } } else { if lsess > 0 { if encodeSession, err := encodeGob(session); err == nil { sessionSign := s.new(rw) writeFile(s.sessionDir+sessionSign+".golanger", encodeSession) } else { log.Error("<SessionManager.Set> ", "encodeGob:", err) } } } }
func decodeCookie(encodedCookie string, key, iv []byte) (map[string]interface{}, error) { sessionBytes, err := base64.URLEncoding.DecodeString(encodedCookie) if err != nil { log.Error("<decodeCookie> ", "base64.Decodestring:", err) return nil, err } aesCipher, err := aes.NewCipher(key) if err != nil { log.Error("<decodeCookie> ", "aes.NewCipher:", err) return nil, err } decrypter := cipher.NewCBCDecrypter(aesCipher, iv) decrypter.CryptBlocks(sessionBytes, sessionBytes) buf := bytes.NewBuffer(sessionBytes) var gobLen int32 binary.Read(buf, binary.BigEndian, &gobLen) gobBytes := sessionBytes[4 : 4+gobLen] session, err := decodeGob(gobBytes) if err != nil { log.Error("<decodeCookie> ", "decodeGob:", err) return nil, err } return session, nil }
func (p *Page) setGlobalTpl(globalTplModTime int64, reset bool) { if globalTpls, err := filepath.Glob(p.Config.TemplateDirectory + p.Config.ThemeDirectory + p.Config.TemplateGlobalDirectory + p.Config.TemplateGlobalFile); err == nil && globalTpls != nil && len(globalTpls) > 0 { var buf bytes.Buffer for _, tpl := range globalTpls { if b, err := ioutil.ReadFile(tpl); err == nil { buf.Write(b) } else { log.Error("<Page.setGlobalTpl> ", err) } } sBuf := strings.TrimSpace(buf.String()) if sBuf != "" { p.site.SetTemplateCacheObject("globalTpl", buf.String(), globalTplModTime) if reset { newT := template.New("globalTpl").Funcs(p.site.templateFunc) if t, err := newT.Parse(sBuf); t != nil { p.site.globalTemplate = t } else { log.Error("<Page.setGlobalTpl> ", err) } } else { if t, err := p.site.globalTemplate.Parse(sBuf); t != nil { p.site.globalTemplate = t } else { log.Error("<Page.setGlobalTpl> ", err) } } } } }
func (s *SessionManager) Get(rw http.ResponseWriter, req *http.Request) map[string]interface{} { m := map[string]interface{}{} if c, err := req.Cookie(s.CookieName); err == nil { sessionSign := c.Value if content, err := readFile(s.sessionDir + sessionSign + ".golanger"); err == nil { if len(content) > 0 { if dm, err := decodeGob(content); err == nil { m = dm } else { log.Error("<SessionManager.Get> ", "decodeGob:", err) } } } } else { s.new(rw) } return m }
func encodeCookie(content map[string]interface{}, key, iv []byte) (string, error) { sessionGob, err := encodeGob(content) if err != nil { log.Error("<encodeCookie> ", err) return "", err } //实现动态填充,达到aes.BlockSize的倍数,+4是为了后面提供4个字节来保存字符串长度使用的 padLen := aes.BlockSize - (len(sessionGob)+4)%aes.BlockSize buf := bytes.NewBuffer(nil) var sessionLen int32 = (int32)(len(sessionGob)) binary.Write(buf, binary.BigEndian, sessionLen) buf.WriteString(sessionGob) buf.WriteString(strings.Repeat("\000", padLen)) sessionBytes := buf.Bytes() aesCipher, err := aes.NewCipher(key) if err != nil { return "", err } encrypter := cipher.NewCBCEncrypter(aesCipher, iv) encrypter.CryptBlocks(sessionBytes, sessionBytes) b64 := base64.URLEncoding.EncodeToString(sessionBytes) return b64, nil }
func (p *Page) routeTemplate(w http.ResponseWriter, r *http.Request) { if p.Config.AutoGenerateHtml { p.Document.GenerateHtml = true } if p.Document.Close == false && p.Document.Hide == false { if globalTplFi, err := os.Stat(p.Config.TemplateDirectory + p.Config.ThemeDirectory + p.Config.TemplateGlobalDirectory); err != nil { log.Error("<Page.routeTemplate> ", err) } else { if globalTplCache := p.site.GetTemplateCache("globalTpl"); globalTplCache.ModTime > 0 { if globalTplFi.ModTime().Unix() > globalTplCache.ModTime { p.setGlobalTpl(globalTplFi.ModTime().Unix(), true) } } } if tplFi, err := os.Stat(p.Config.TemplateDirectory + p.Config.ThemeDirectory + p.Template); err != nil { p.site.base.rmutex.RLock() tmplCache := p.site.GetTemplateCache(p.Template) if tmplCache.ModTime > 0 { p.site.base.mutex.Lock() p.DelTemplateCache(p.Template) p.site.base.mutex.Unlock() log.Info("<Page.routeTemplate> ", "Delete Template Cache:", p.Template) } p.site.base.rmutex.RUnlock() } else { p.site.base.rmutex.RLock() tmplCache := p.site.GetTemplateCache(p.Template) if tplFi.ModTime().Unix() > tmplCache.ModTime { p.site.base.mutex.Lock() p.SetTemplateCache(p.Template, p.Config.TemplateDirectory+p.Config.ThemeDirectory+p.Template) p.site.base.mutex.Unlock() tmplCache = p.site.GetTemplateCache(p.Template) } globalTemplate, _ := p.site.globalTemplate.Clone() pageTemplate, err := globalTemplate.New(filepath.Base(p.Template)).Parse(tmplCache.Content) p.site.base.rmutex.RUnlock() if err != nil { log.Error("<Page.routeTemplate> ", err) w.Write([]byte(fmt.Sprint(err))) } else { templateVar := map[string]interface{}{ "G": p.GET, "P": p.POST, "S": p.SESSION, "O_S": p.ONCE_SESSION, "C": p.COOKIE, "CS": p.COOKIE_SESSION, "D": p.Document, "L": p.LANG, "Config": p.Config.M, "Template": p.Template, } p.site.base.rmutex.RLock() templateVar["Siteroot"] = p.site.Root templateVar["Version"] = p.site.Version p.site.base.rmutex.RUnlock() if !p.Document.GenerateHtml { err := pageTemplate.Execute(w, templateVar) if err != nil { log.Error("<Page.routeTemplate> ", err) w.Write([]byte(fmt.Sprint(err))) } } else { htmlFile := "" p.site.base.rmutex.RLock() assetsHtmlDir := p.Config.AssetsDirectory + p.Config.HtmlDirectory if strings.HasPrefix(p.Template, p.Config.IndexDirectory) { htmlFile = assetsHtmlDir + strings.Replace(p.Template, p.Config.IndexDirectory, "", 1) } else { htmlFile = assetsHtmlDir + p.Template } if r.URL.RawQuery != "" { htmlFile += "?" + r.URL.RawQuery } p.site.base.rmutex.RUnlock() htmlDir := filepath.Dir(htmlFile) if htmlDirFi, err := os.Stat(htmlDir); err != nil || !htmlDirFi.IsDir() { os.MkdirAll(htmlDir, 0777) log.Info("<Page.routeTemplate> ", "MkdirAll:", htmlDir) } htmlFi, htmlErr := os.Stat(htmlFile) if p.checkHtmlDoWrite(tplFi, htmlFi, htmlErr) { if file, err := os.OpenFile(htmlFile, os.O_CREATE|os.O_WRONLY, 0777); err != nil { log.Error("<Page.routeTemplate> ", err) } else { if p.Config.AutoJumpToHtml || p.Config.ChangeSiteRoot { templateVar["Siteroot"] = p.site.Root + p.Config.HtmlDirectory } pageTemplate.Execute(file, templateVar) } } if p.Config.AutoJumpToHtml { p.site.base.rmutex.RLock() http.Redirect(w, r, p.site.Root+htmlFile[2:], http.StatusFound) p.site.base.rmutex.RUnlock() } else if p.Config.AutoLoadStaticHtml && htmlFi != nil && htmlErr == nil { htmlContent, err := ioutil.ReadFile(htmlFile) if err == nil { w.Write(htmlContent) } else { log.Error("<Page.routeTemplate> ", err) } } else { err := pageTemplate.Execute(w, templateVar) if err != nil { log.Error("<Page.routeTemplate> ", err) } } } } } } }
func (p *Page) routeController(i interface{}, w http.ResponseWriter, r *http.Request) { pageOriController := p.GetController(p.currentPath) rv := reflect.ValueOf(pageOriController) rvw, rvr := reflect.ValueOf(w), reflect.ValueOf(r) rt := rv.Type() vpc := reflect.New(rt) iv := reflect.ValueOf(i).Elem() vapc := vpc.Elem().FieldByName("Application") vapc.Set(iv) tapc := vapc.Type() if _, found := tapc.FieldByName("RW"); found { vapc.FieldByName("RW").Set(rvw) } if _, found := tapc.FieldByName("R"); found { vapc.FieldByName("R").Set(rvr) } vppc := vapc.FieldByName("Page") ppc := vppc.Addr().Interface().(*Page) log.Debug("<Page.routeController> ", "ppc.Config.LoadStaticHtmlWithLogic:", ppc.Config.LoadStaticHtmlWithLogic) log.Debug("<Page.routeController> ", "ppc.Config.AutoGenerateHtml:", ppc.Config.AutoGenerateHtml) if !ppc.Config.LoadStaticHtmlWithLogic && ppc.Config.AutoGenerateHtml { tplFi, tplErr := os.Stat(ppc.Config.TemplateDirectory + ppc.Config.ThemeDirectory + ppc.Template) if tplErr != nil { log.Error("<Page.routeController> ", tplErr) } else { ppc.site.base.rmutex.RLock() tmplCache := ppc.site.GetTemplateCache(ppc.Template) ppc.site.base.rmutex.RUnlock() if tplFi.ModTime().Unix() > tmplCache.ModTime { goto DO_ROUTER } } htmlFile := "" ppc.site.base.rmutex.RLock() assetsHtmlDir := ppc.Config.AssetsDirectory + ppc.Config.HtmlDirectory if strings.HasPrefix(ppc.Template, ppc.Config.IndexDirectory) { htmlFile = assetsHtmlDir + strings.Replace(ppc.Template, ppc.Config.IndexDirectory, "", 1) } else { htmlFile = assetsHtmlDir + ppc.Template } if r.URL.RawQuery != "" { htmlFile += "?" + r.URL.RawQuery } ppc.site.base.rmutex.RUnlock() if htmlFi, htmlErr := os.Stat(htmlFile); htmlErr == nil { if ppc.checkHtmlDoWrite(tplFi, htmlFi, htmlErr) { goto DO_ROUTER } htmlContent, err := ioutil.ReadFile(htmlFile) if err == nil { w.Write(htmlContent) return } else { goto DO_ROUTER } } else { goto DO_ROUTER } } DO_ROUTER: tpc := vpc.Type() if ppc.CurrentAction != "Init" { ppc.callMethod(tpc, vpc, "Init", rvr, rvw) } if _, ok := tpc.MethodByName(ppc.CurrentAction); ok && ppc.filterMethod(ppc.CurrentAction) { ppc.filterDoMethod(tpc, vpc, "Before_", rvr, rvw) ppc.callMethod(tpc, vpc, "Before_"+ppc.CurrentAction, rvr, rvw) if ppc.Document.Close == false { ppc.callMethod(tpc, vpc, ppc.CurrentAction, rvr, rvw) } ppc.callMethod(tpc, vpc, "After_"+ppc.CurrentAction, rvr, rvw) ppc.filterDoMethod(tpc, vpc, "After_", rvr, rvw) } else { if !strings.Contains(tpc.String(), "Page404") { notFountRV := reflect.ValueOf(ppc.NotFoundtController) notFountRT := notFountRV.Type() vnpc := reflect.New(notFountRT) vanpc := vnpc.Elem().FieldByName("Application") vanpc.Set(vapc) vpnpc := vanpc.FieldByName("Page") vpnpc.Set(vppc) ppc = vpnpc.Addr().Interface().(*Page) tnpc := vnpc.Type() ppc.callMethod(tnpc, vnpc, "Init", rvr, rvw) } } if ppc.site.supportSession { switch ppc.Config.SessionType { case "file": ppc.FileSession.Set(ppc.SESSION, w, r) case "memory": ppc.Session.Set(w, r) default: ppc.Session.Set(w, r) } } if ppc.site.supportCookieSession { ppc.CookieSession.Set(ppc.COOKIE_SESSION, w, r) } if ppc.Config.SupportTemplate { ppc.setStaticDocument() ppc.routeTemplate(w, r) } }
func (p *Page) reset(update bool) { p.setLog(p.Config.SupportLog, p.Config.LogWriteTo, p.Config.LogLevel) p.setUrlManage(p.Config.SupportUrlManage, p.Config.UrlManageRule) if update { if p.site.supportSession != p.Config.SupportSession { p.site.supportSession = p.Config.SupportSession } if p.site.supportCookieSession != p.Config.SupportCookieSession { p.site.supportCookieSession = p.Config.SupportCookieSession } if p.site.supportI18n != p.Config.SupportI18n { p.site.supportI18n = p.Config.SupportI18n } if p.Document.Theme != p.Config.Theme { p.Document.Theme = p.Config.Theme } if p.Document.Static != p.Config.SiteRoot+p.Config.StaticDirectory { p.Document.Static = p.Config.SiteRoot + p.Config.StaticDirectory } if p.site.Root == p.Config.SiteRoot { return } else { log.Info("<Page.reset> ", "p.Config.SiteRoot be changed:", p.Config.SiteRoot) p.SetDefaultController(p.GetController(p.Config.IndexDirectory)) p.UpdateController(p.site.Root, p.Config.SiteRoot, p.DefaultController) p.site.Root = p.Config.SiteRoot } } else { p.site.supportSession = p.Config.SupportSession p.site.supportCookieSession = p.Config.SupportCookieSession p.site.supportI18n = p.Config.SupportI18n p.Document.Theme = p.Config.Theme p.site.Root = p.Config.SiteRoot p.Document.Static = p.site.Root + p.Config.StaticDirectory p.SetDefaultController(p.GetController(p.Config.IndexDirectory)) p.RegisterController(p.site.Root, p.DefaultController) p.site.globalTemplate = template.New("globalTpl").Funcs(p.site.templateFunc) } if globalCssFi, err := os.Stat(p.Config.StaticCssDirectory + "/global/"); err == nil && globalCssFi.IsDir() { DcssPath := p.Config.StaticCssDirectory + "global/" p.Document.Css["global"] = p.site.Root + DcssPath[len(p.Config.AssetsDirectory):] log.Debug("<Page.reset> ", `p.Document.Css["global"]:`, p.Document.Css["global"]) if _, err := os.Stat(DcssPath + "global.css"); err == nil { p.Document.GlobalCssFile = p.Document.Css["global"] + "global.css" } } if globalJsFi, err := os.Stat(p.Config.StaticJsDirectory + "/global/"); err == nil && globalJsFi.IsDir() { DjsPath := p.Config.StaticJsDirectory + "global/" p.Document.Js["global"] = p.site.Root + DjsPath[len(p.Config.AssetsDirectory):] log.Debug("<Page.reset> ", `p.Document.Js["global"]:`, p.Document.GlobalCssFile) if _, err := os.Stat(DjsPath + "global.js"); err == nil { p.Document.GlobalJsFile = p.Document.Js["global"] + "global.js" } } if globalImgFi, err := os.Stat(p.Config.StaticImgDirectory + "/global/"); err == nil && globalImgFi.IsDir() { DimgPath := p.Config.StaticImgDirectory + "global/" p.Document.Img["global"] = p.site.Root + DimgPath[len(p.Config.AssetsDirectory):] log.Debug("<Page.reset> ", `p.Document.Img["global"]:`, p.Document.Img["global"]) } if globalTplFi, err := os.Stat(p.Config.TemplateDirectory + p.Config.ThemeDirectory + p.Config.TemplateGlobalDirectory); err != nil { log.Error("<Page.reset> ", err) } else { p.setGlobalTpl(globalTplFi.ModTime().Unix(), false) } }