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 }
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: } }
// 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() }
// 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 (c *Cookie) Send(ctx echo.Context) { ctx.Response().Header().Set("Set-Cookie", c.cookie.String()) }