func (c *Config) Expired(rule *Rule, ctx echo.Context, saveFile string) (int64, bool) { var expired int64 if rule.ExpireTime > 0 { expired = int64(rule.ExpireTime) } else if rule.ExpireFunc != nil { return rule.ExpireFunc(saveFile, ctx) } else { switch c.HtmlCacheTime.(type) { case int: expired = int64(c.HtmlCacheTime.(int)) case int64: expired = c.HtmlCacheTime.(int64) case func(string, echo.Context) (int64, bool): fn := c.HtmlCacheTime.(func(string, echo.Context) (int64, bool)) return fn(saveFile, ctx) } } mtime, err := com.FileMTime(saveFile) if err != nil { ctx.Object().Echo().Logger().Debug(err) } if mtime == 0 { return mtime, true } if time.Now().Local().Unix() > mtime+expired { return mtime, true } return mtime, false }
// OverrideRequestMethod overrides the http // request's method with the specified method. func OverrideRequestMethod(c echo.Context, method string) error { if !isValidOverrideMethod(method) { return ErrInvalidOverrideMethod } c.Request().Header().Set(HeaderHTTPMethodOverride, method) return nil }
func sleep(e echo.Context, d time.Duration) { w := e.Response() var clientGone <-chan bool if cn, ok := w.(http.CloseNotifier); ok { clientGone = cn.CloseNotify() } select { case <-time.After(d): case <-clientGone: } }
func (c *Config) Write(b []byte, ctx echo.Context) bool { if !c.HtmlCacheOn || ctx.Request().Method() != `GET` || X.X(ctx).Code != http.StatusOK { return false } tmpl := X.MustString(ctx, `webx:saveHtmlFile`) if tmpl == `` { return false } if err := com.WriteFile(tmpl, b); err != nil { ctx.Object().Echo().Logger().Debug(err) } return true }
func HttpCache(ctx echo.Context, eTag interface{}, etagValidator func(oldEtag, newEtag string) bool) bool { var etag string if eTag == nil { etag = fmt.Sprintf(`%v`, time.Now().UTC().Unix()) } else { etag = fmt.Sprintf(`%v`, eTag) } resp := ctx.Response() //resp.Header().Set(`Connection`, `keep-alive`) resp.Header().Set(`X-Cache`, `HIT from Webx-Page-Cache`) if inm := ctx.Request().Header().Get("If-None-Match"); inm != `` { var valid bool if etagValidator != nil { valid = etagValidator(inm, etag) } else { valid = inm == etag } if valid { resp.Header().Del(`Content-Type`) resp.Header().Del(`Content-Length`) resp.WriteHeader(http.StatusNotModified) ctx.Object().Echo().Logger().Debugf(`%v is not modified.`, ctx.Path()) return true } } resp.Header().Set(`Etag`, etag) resp.Header().Set(`Cache-Control`, `public,max-age=1`) return false }
// Index responds with the pprof-formatted profile named by the request. // For example, "/debug/pprof/heap" serves the "heap" profile. // Index responds to a request for "/debug/pprof/" with an HTML page // listing the available profiles. func Index(e echo.Context) { r := e.Request() w := e.Response() if strings.HasPrefix(r.URL().Path(), "/debug/pprof/") { name := strings.TrimPrefix(r.URL().Path(), "/debug/pprof/") if name != "" { handler(name).ServeHTTP(e) return } } profiles := pprof.Profiles() if err := indexTmpl.Execute(w, profiles); err != nil { log.Print(err) } }
// Symbol looks up the program counters listed in the request, // responding with a table mapping program counters to function names. // The package initialization registers it as /debug/pprof/symbol. func Symbol(e echo.Context) { w := e.Response() r := e.Request() w.Header().Set("Content-Type", "text/plain; charset=utf-8") // We have to read the whole POST body before // writing any output. Buffer the output here. var buf bytes.Buffer // We don't know how many symbols we have, but we // do have symbol information. Pprof only cares whether // this number is 0 (no symbols available) or > 0. fmt.Fprintf(&buf, "num_symbols: 1\n") var b *bufio.Reader if r.Method() == "POST" { b = bufio.NewReader(r.Body()) } else { b = bufio.NewReader(strings.NewReader(r.URL().RawQuery())) } for { word, err := b.ReadSlice('+') if err == nil { word = word[0 : len(word)-1] // trim + } pc, _ := strconv.ParseUint(string(word), 0, 64) if pc != 0 { f := runtime.FuncForPC(uintptr(pc)) if f != nil { fmt.Fprintf(&buf, "%#x %s\n", pc, f.Name()) } } // Wait until here to check for err; the last // symbol will have an err because it doesn't end in +. if err != nil { if err != io.EOF { fmt.Fprintf(&buf, "reading request: %v\n", err) } break } } w.Write(buf.Bytes()) }
func (name handler) ServeHTTP(e echo.Context) { w := e.Response() r := e.Request() w.Header().Set("Content-Type", "text/plain; charset=utf-8") debug, _ := strconv.Atoi(r.FormValue("debug")) p := pprof.Lookup(string(name)) if p == nil { w.WriteHeader(404) fmt.Fprintf(w, "Unknown profile: %s\n", name) return } gc, _ := strconv.Atoi(r.FormValue("gc")) if name == "heap" && gc > 0 { runtime.GC() } p.WriteTo(w, debug) return }
// Trace responds with the execution trace in binary form. // Tracing lasts for duration specified in seconds GET parameter, or for 1 second if not specified. // The package initialization registers it as /debug/pprof/trace. func Trace(e echo.Context) { w := e.Response() r := e.Request() sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64) if sec == 0 { sec = 1 } // Set Content Type assuming trace.Start will work, // because if it does it starts writing. w.Header().Set("Content-Type", "application/octet-stream") if err := trace.Start(w); err != nil { // trace.Start failed, so no writes yet. // Can change header back to text content and send error code. w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Could not enable tracing: %s\n", err) return } sleep(e, time.Duration(sec)*time.Second) trace.Stop() }
func (c *Xsrf) Register(ctx echo.Context) { ctx.SetFunc("XsrfForm", func() template.HTML { return c.Form(ctx) }) ctx.SetFunc("XsrfValue", func() string { return c.Value(ctx) }) ctx.SetFunc("XsrfName", func() string { return c.FieldName }) }
func MustInt64(c echo.Context, k string) (r int64) { if v, ok := c.Get(k).(int64); ok { r = v } return }
func MustBool(c echo.Context, k string) (r bool) { if v, ok := c.Get(k).(bool); ok { r = v } return }
func MustString(c echo.Context, k string) (r string) { if v, ok := c.Get(k).(string); ok { r = v } return }
func (j *JWT) Ignore(on bool, c echo.Context) { c.Set(`webx:ignoreJwt`, on) }
func (j *JWT) Claims(c echo.Context) map[string]interface{} { r, _ := c.Get(`webx:jwtClaims`).(map[string]interface{}) return r }
func (c *Config) Read(ctx echo.Context) bool { ct := X.X(ctx) req := ctx.Request() if !c.HtmlCacheOn || req.Method() != `GET` { return false } p := strings.Trim(req.URL().Path(), `/`) if p == `` { p = `index` } s := strings.SplitN(p, `/`, 3) if c.htmlCacheRules == nil { c.htmlCacheRules = make(map[string]*Rule) for key, rule := range c.HtmlCacheRules { c.htmlCacheRules[key] = c.Rule(rule) } } var rule *Rule switch len(s) { case 2: k := s[0] + `:` + s[1] if v, ok := c.htmlCacheRules[k]; ok { rule = v } else if v, ok := c.htmlCacheRules[s[1]]; ok { rule = v } else { k = s[0] + `:` if v, ok := c.htmlCacheRules[k]; ok { rule = v } } case 1: k := s[0] + `:` if v, ok := c.htmlCacheRules[k]; ok { rule = v } } var saveFile string = c.SaveFileName(rule, ctx) if saveFile == "" { return false } if ct.Format != `` { saveFile += `.` + ct.Format } mtime, expired := c.Expired(rule, ctx, saveFile) if expired { ctx.Set(`webx:saveHtmlFile`, saveFile) return false } //_ = mtime //ctx.File(saveFile, ``, false) if !HttpCache(ctx, mtime, nil) { html, err := com.ReadFile(saveFile) if err != nil { ctx.Object().Echo().Logger().Error(err) } Output(html, ct) } ct.Exit = true return true }
func (c *Cookie) Send(ctx echo.Context) { ctx.Response().Header().Set("Set-Cookie", c.cookie.String()) }
func MustFloat64(c echo.Context, k string) (r float64) { if v, ok := c.Get(k).(float64); ok { r = v } return }
// Cmdline responds with the running program's // command line, with arguments separated by NUL bytes. // The package initialization registers it as /debug/pprof/cmdline. func Cmdline(e echo.Context) { w := e.Response() w.Header().Set("Content-Type", "text/plain; charset=utf-8") fmt.Fprintf(w, strings.Join(os.Args, "\x00")) }
func MustUint8(c echo.Context, k string) (r uint8) { if v, ok := c.Get(k).(uint8); ok { r = v } return }
func (c *Xsrf) Ignore(on bool, ctx echo.Context) { ctx.Set(`webx:ignoreXsrf`, on) }