func mainHandler(ctx *fasthttp.RequestCtx) { // Performance hack for prefork mode - periodically close keepalive // connections for evenly distributing connections among available // processes. if *prefork { maxDuration := maxConnDuration + time.Millisecond*time.Duration(atomic.LoadUint64(&connDurationJitter)) if time.Since(ctx.ConnTime()) > maxDuration { atomic.StoreUint64(&connDurationJitter, uint64(rand.Intn(100))) ctx.SetConnectionClose() } } path := ctx.Path() switch string(path) { case "/plaintext": plaintextHandler(ctx) case "/json": jsonHandler(ctx) case "/db": dbHandler(ctx) case "/queries": queriesHandler(ctx) case "/fortune": fortuneHandler(ctx) case "/update": updateHandler(ctx) default: ctx.Error("unexpected path", fasthttp.StatusBadRequest) } }
func idHandlerFunc(ctx *fasthttp.RequestCtx, idWorker *goflake.IdWorker, retry int) { ua := string(ctx.UserAgent()) var ( id uint64 err error ) for i := 0; i < retry; i++ { id, err = idWorker.GetId(ua) if err == nil { break } } r := map[string]string{ "id": strconv.FormatUint(id, 10), } if strings.HasSuffix(string(ctx.Path()), ".msgpack") { ctx.SetContentType("application/x-msgpack; charset=UTF-8") if err := codec.NewEncoder(ctx, mh).Encode(r); err != nil { ctx.Error(err.Error(), fasthttp.StatusInternalServerError) } } else { ctx.SetContentType("application/json; charset=UTF-8") if err := json.NewEncoder(ctx).Encode(r); err != nil { ctx.Error(fmt.Sprintf(`{"error":"%v"}`, err.Error()), fasthttp.StatusInternalServerError) } } }
func (s *Selector) Match(ctx *fasthttp.RequestCtx) (string, bool) { var matchSlice []byte found := false switch s.RequestAttr { case "IP": matchSlice = []byte(ctx.RemoteIP().String()) case "Method": matchSlice = ctx.Method() case "Path": matchSlice = ctx.Path() case "Host": matchSlice = ctx.Host() case "POST": matchSlice = ctx.PostArgs().Peek(s.SubAttr) case "GET": matchSlice = ctx.QueryArgs().Peek(s.SubAttr) case "Param": matchSlice = ctx.PostArgs().Peek(s.SubAttr) if matchSlice == nil { matchSlice = ctx.QueryArgs().Peek(s.SubAttr) } case "Header": matchSlice = ctx.Request.Header.Peek(s.SubAttr) default: log.Println("unknown request attribute:", s.RequestAttr) } if matchSlice != nil && (s.Regexp == nil || s.Regexp.Match(matchSlice)) { found = true } if s.Negate { found = !found } return string(matchSlice), found }
func requestHandler(ctx *fasthttp.RequestCtx) { fmt.Fprintf(ctx, "Hello, world!\n\n") fmt.Fprintf(ctx, "Request method is %q\n", ctx.Method()) fmt.Fprintf(ctx, "RequestURI is %q\n", ctx.RequestURI()) fmt.Fprintf(ctx, "Requested path is %q\n", ctx.Path()) fmt.Fprintf(ctx, "Host is %q\n", ctx.Host()) fmt.Fprintf(ctx, "Query string is %q\n", ctx.QueryArgs()) fmt.Fprintf(ctx, "User-Agent is %q\n", ctx.UserAgent()) fmt.Fprintf(ctx, "Connection has been established at %s\n", ctx.ConnTime()) fmt.Fprintf(ctx, "Request has been started at %s\n", ctx.Time()) fmt.Fprintf(ctx, "Serial request number for the current connection is %d\n", ctx.ConnRequestNum()) fmt.Fprintf(ctx, "Your ip is %q\n\n", ctx.RemoteIP()) fmt.Fprintf(ctx, "Raw request is:\n---CUT---\n%s\n---CUT---", &ctx.Request) ctx.SetContentType("text/plain; charset=utf8") // Set arbitrary headers ctx.Response.Header.Set("X-My-Header", "my-header-value") // Set cookies var c fasthttp.Cookie c.SetKey("cookie-name") c.SetValue("cookie-value") ctx.Response.Header.SetCookie(&c) }
func fastHTTPHandler(ctx *fasthttp.RequestCtx) { if string(ctx.Method()) == "GET" { switch string(ctx.Path()) { case "/rest/hello": ctx.Write([]byte("Hello world")) default: ctx.Error("Unsupported path", fasthttp.StatusNotFound) } return } }
// Main request handler func requestHandler(ctx *fasthttp.RequestCtx) { path := ctx.Path() switch { case bytes.HasPrefix(path, imgPrefix): imgHandler(ctx) case bytes.HasPrefix(path, cssPrefix): cssHandler(ctx) default: filesHandler(ctx) } }
//fasthttp func fastHttpRawHandler(ctx *fasthttp.RequestCtx) { if string(ctx.Method()) == "GET" { switch string(ctx.Path()) { case "/hello": if sleepTime > 0 { time.Sleep(sleepTimeDuration) } ctx.Write(message) default: ctx.Error("Unsupported path", fasthttp.StatusNotFound) } return } ctx.Error("Unsupported method", fasthttp.StatusMethodNotAllowed) }
func (g *Goka) Serve(rCtx *fasthttp.RequestCtx) { c := g.pool.Get().(*Context) h, g := g.router.Find(string(rCtx.Method()), string(rCtx.Path()), c) c.reset(rCtx, g) for i := len(g.middleware) - 1; i >= 0; i-- { h = g.middleware[i](h) } if err := h(c); err != nil { g.httpErrorHandler(err, c) } g.pool.Put(c) }
func mainHandler(ctx *fasthttp.RequestCtx) { path := ctx.Path() switch string(path) { case "/plaintext": plaintextHandler(ctx) case "/json": jsonHandler(ctx) case "/db": dbHandler(ctx) case "/queries": queriesHandler(ctx) case "/fortune": fortuneHandler(ctx) case "/update": updateHandler(ctx) default: ctx.Error("unexpected path", fasthttp.StatusBadRequest) } }
func (a *API) Handler(ctx *fasthttp.RequestCtx) { ctx.SetContentType("application/json") ctx.Response.Header.Set("Access-Control-Allow-Origin", "*") switch string(ctx.Path()) { case "/rules": j, err := json.Marshal(a.Proxy.Rules) if err != nil { ctx.Error(fmt.Sprintf("{\"error\": \"%v\"}", err), 500) return } ctx.Write(j) case "/rules/reload": if err := a.Proxy.ReloadRules(a.RuleFile); err != nil { ctx.Error(fmt.Sprintf("{\"error\": \"%v\"}", err), 500) return } log.Println("Rule file reloaded") ctx.Write([]byte("{\"status\": \"ok\"}")) default: ctx.Error("{\"error\": \"Not found\"}", fasthttp.StatusNotFound) } }
// Handler makes the router implement the fasthttp.ListenAndServe interface. func (r *Router) Handler(ctx *fasthttp.RequestCtx) { if r.PanicHandler != nil { defer r.recv(ctx) } method := string(ctx.Method()) if root := r.trees[method]; root != nil { path := string(ctx.Path()) if f, ps, tsr := root.getValue(path); f != nil { f(ctx, ps) return } else if method != "CONNECT" && path != "/" { code := 301 // Permanent redirect, request with GET method if method != "GET" { // Temporary redirect, request with same method // As of Go 1.3, Go does not support status code 308. code = 307 } if tsr && r.RedirectTrailingSlash { var uri string if len(path) > 1 && path[len(path)-1] == '/' { uri = path[:len(path)-1] } else { uri = path + "/" } ctx.Redirect(uri, code) return } // Try to fix the request path if r.RedirectFixedPath { fixedPath, found := root.findCaseInsensitivePath( CleanPath(path), r.RedirectTrailingSlash, ) if found { uri := string(fixedPath) ctx.Redirect(uri, code) return } } } } // Handle 405 if r.HandleMethodNotAllowed { for method := range r.trees { // Skip the requested method - we already tried this one if method == string(ctx.Method()) { continue } f, _, _ := r.trees[method].getValue(string(ctx.Path())) if f != nil { if r.MethodNotAllowed != nil { r.MethodNotAllowed(ctx) } else { ctx.Error(fasthttp.StatusMessage(fasthttp.StatusMethodNotAllowed), fasthttp.StatusMethodNotAllowed) } return } } } // Handle 404 if r.NotFound != nil { r.NotFound(ctx) } else { ctx.Error(fasthttp.StatusMessage(fasthttp.StatusNotFound), fasthttp.StatusNotFound) } }
// Handler makes the router implement the fasthttp.ListenAndServe interface. func (r *Router) Handler(ctx *fasthttp.RequestCtx) { if r.PanicHandler != nil { defer r.recv(ctx) } path := string(ctx.Path()) method := string(ctx.Method()) if root := r.trees[method]; root != nil { if f, ps, tsr := root.getValue(path); f != nil { f(ctx, ps) return } else if method != "CONNECT" && path != "/" { code := 301 // Permanent redirect, request with GET method if method != "GET" { // Temporary redirect, request with same method // As of Go 1.3, Go does not support status code 308. code = 307 } if tsr && r.RedirectTrailingSlash { var uri string if len(path) > 1 && path[len(path)-1] == '/' { uri = path[:len(path)-1] } else { uri = path + "/" } ctx.Redirect(uri, code) return } // Try to fix the request path if r.RedirectFixedPath { fixedPath, found := root.findCaseInsensitivePath( CleanPath(path), r.RedirectTrailingSlash, ) if found { uri := string(fixedPath) ctx.Redirect(uri, code) return } } } } if method == "OPTIONS" { // Handle OPTIONS requests if r.HandleOPTIONS { if allow := r.allowed(path, method); len(allow) > 0 { ctx.Response.Header.Set("Allow", allow) return } } } else { // Handle 405 if r.HandleMethodNotAllowed { if allow := r.allowed(path, method); len(allow) > 0 { ctx.Response.Header.Set("Allow", allow) if r.MethodNotAllowed != nil { r.MethodNotAllowed(ctx) } else { ctx.SetStatusCode(fasthttp.StatusMethodNotAllowed) ctx.SetContentTypeBytes(defaultContentType) ctx.SetBodyString(fasthttp.StatusMessage(fasthttp.StatusMethodNotAllowed)) } return } } } // Handle 404 if r.NotFound != nil { r.NotFound(ctx) } else { ctx.Error(fasthttp.StatusMessage(fasthttp.StatusNotFound), fasthttp.StatusNotFound) } }
// request handler in net/http style, i.e. method bound to MyHandler struct. func (h *MyHandler) HandleFastHTTP(ctx *fasthttp.RequestCtx) { // notice that we may access MyHandler properties here - see h.foobar. fmt.Fprintf(ctx, "Hello, world! Requested path is %q. Foobar is %q", ctx.Path(), h.foobar) }