code.gitea.io/gitea@v1.19.3/modules/web/wrap_convert.go (about)

     1  // Copyright 2021 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package web
     5  
     6  import (
     7  	goctx "context"
     8  	"fmt"
     9  	"net/http"
    10  
    11  	"code.gitea.io/gitea/modules/context"
    12  	"code.gitea.io/gitea/modules/web/routing"
    13  )
    14  
    15  type wrappedHandlerFunc func(resp http.ResponseWriter, req *http.Request, others ...wrappedHandlerFunc) (done bool, deferrable func())
    16  
    17  func convertHandler(handler interface{}) wrappedHandlerFunc {
    18  	funcInfo := routing.GetFuncInfo(handler)
    19  	switch t := handler.(type) {
    20  	case http.HandlerFunc:
    21  		return func(resp http.ResponseWriter, req *http.Request, others ...wrappedHandlerFunc) (done bool, deferrable func()) {
    22  			routing.UpdateFuncInfo(req.Context(), funcInfo)
    23  			if _, ok := resp.(context.ResponseWriter); !ok {
    24  				resp = context.NewResponse(resp)
    25  			}
    26  			t(resp, req)
    27  			if r, ok := resp.(context.ResponseWriter); ok && r.Status() > 0 {
    28  				done = true
    29  			}
    30  			return done, deferrable
    31  		}
    32  	case func(http.ResponseWriter, *http.Request):
    33  		return func(resp http.ResponseWriter, req *http.Request, others ...wrappedHandlerFunc) (done bool, deferrable func()) {
    34  			routing.UpdateFuncInfo(req.Context(), funcInfo)
    35  			t(resp, req)
    36  			if r, ok := resp.(context.ResponseWriter); ok && r.Status() > 0 {
    37  				done = true
    38  			}
    39  			return done, deferrable
    40  		}
    41  
    42  	case func(ctx *context.Context):
    43  		return func(resp http.ResponseWriter, req *http.Request, others ...wrappedHandlerFunc) (done bool, deferrable func()) {
    44  			routing.UpdateFuncInfo(req.Context(), funcInfo)
    45  			ctx := context.GetContext(req)
    46  			t(ctx)
    47  			done = ctx.Written()
    48  			return done, deferrable
    49  		}
    50  	case func(ctx *context.Context) goctx.CancelFunc:
    51  		return func(resp http.ResponseWriter, req *http.Request, others ...wrappedHandlerFunc) (done bool, deferrable func()) {
    52  			routing.UpdateFuncInfo(req.Context(), funcInfo)
    53  			ctx := context.GetContext(req)
    54  			deferrable = t(ctx)
    55  			done = ctx.Written()
    56  			return done, deferrable
    57  		}
    58  	case func(*context.APIContext):
    59  		return func(resp http.ResponseWriter, req *http.Request, others ...wrappedHandlerFunc) (done bool, deferrable func()) {
    60  			routing.UpdateFuncInfo(req.Context(), funcInfo)
    61  			ctx := context.GetAPIContext(req)
    62  			t(ctx)
    63  			done = ctx.Written()
    64  			return done, deferrable
    65  		}
    66  	case func(*context.APIContext) goctx.CancelFunc:
    67  		return func(resp http.ResponseWriter, req *http.Request, others ...wrappedHandlerFunc) (done bool, deferrable func()) {
    68  			routing.UpdateFuncInfo(req.Context(), funcInfo)
    69  			ctx := context.GetAPIContext(req)
    70  			deferrable = t(ctx)
    71  			done = ctx.Written()
    72  			return done, deferrable
    73  		}
    74  	case func(*context.PrivateContext):
    75  		return func(resp http.ResponseWriter, req *http.Request, others ...wrappedHandlerFunc) (done bool, deferrable func()) {
    76  			routing.UpdateFuncInfo(req.Context(), funcInfo)
    77  			ctx := context.GetPrivateContext(req)
    78  			t(ctx)
    79  			done = ctx.Written()
    80  			return done, deferrable
    81  		}
    82  	case func(*context.PrivateContext) goctx.CancelFunc:
    83  		return func(resp http.ResponseWriter, req *http.Request, others ...wrappedHandlerFunc) (done bool, deferrable func()) {
    84  			routing.UpdateFuncInfo(req.Context(), funcInfo)
    85  			ctx := context.GetPrivateContext(req)
    86  			deferrable = t(ctx)
    87  			done = ctx.Written()
    88  			return done, deferrable
    89  		}
    90  	case func(http.Handler) http.Handler:
    91  		return func(resp http.ResponseWriter, req *http.Request, others ...wrappedHandlerFunc) (done bool, deferrable func()) {
    92  			next := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})
    93  			if len(others) > 0 {
    94  				next = wrapInternal(others)
    95  			}
    96  			routing.UpdateFuncInfo(req.Context(), funcInfo)
    97  			if _, ok := resp.(context.ResponseWriter); !ok {
    98  				resp = context.NewResponse(resp)
    99  			}
   100  			t(next).ServeHTTP(resp, req)
   101  			if r, ok := resp.(context.ResponseWriter); ok && r.Status() > 0 {
   102  				done = true
   103  			}
   104  			return done, deferrable
   105  		}
   106  	default:
   107  		panic(fmt.Sprintf("Unsupported handler type: %#v", t))
   108  	}
   109  }