package context
import (
+ "context"
"fmt"
"io/ioutil"
"net/url"
}
// RepoAssignment returns a middleware to handle repository assignment
-func RepoAssignment(ctx *Context) {
+func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
var (
owner *models.User
err error
ctx.Repo.GitRepo = gitRepo
// We opened it, we should close it
- defer func() {
+ cancel = func() {
// If it's been set to nil then assume someone else has closed it.
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
}
- }()
+ }
// Stop at this point when the repo is empty.
if ctx.Repo.Repository.IsEmpty {
ctx.Data["GoDocDirectory"] = prefix + "{/dir}"
ctx.Data["GoDocFile"] = prefix + "{/dir}/{file}#L{line}"
}
+ return
}
// RepoRefType type of repo reference
// RepoRef handles repository reference names when the ref name is not
// explicitly given
-func RepoRef() func(*Context) {
+func RepoRef() func(*Context) context.CancelFunc {
// since no ref name is explicitly specified, ok to just use branch
return RepoRefByType(RepoRefBranch)
}
// RepoRefByType handles repository reference name for a specific type
// of repository reference
-func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context) {
- return func(ctx *Context) {
+func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context) context.CancelFunc {
+ return func(ctx *Context) (cancel context.CancelFunc) {
// Empty repository does not have reference information.
if ctx.Repo.Repository.IsEmpty {
return
return
}
// We opened it, we should close it
- defer func() {
+ cancel = func() {
// If it's been set to nil then assume someone else has closed it.
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
}
- }()
+ }
}
// Get default branch.
return
}
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
+ return
}
}
package web
import (
+ goctx "context"
"fmt"
"net/http"
"reflect"
switch t := handler.(type) {
case http.HandlerFunc, func(http.ResponseWriter, *http.Request),
func(ctx *context.Context),
+ func(ctx *context.Context) goctx.CancelFunc,
func(*context.APIContext),
func(*context.PrivateContext),
func(http.Handler) http.Handler:
if r, ok := resp.(context.ResponseWriter); ok && r.Status() > 0 {
return
}
+ case func(ctx *context.Context) goctx.CancelFunc:
+ ctx := context.GetContext(req)
+ cancel := t(ctx)
+ if cancel != nil {
+ defer cancel()
+ }
+ if ctx.Written() {
+ return
+ }
case func(ctx *context.Context):
ctx := context.GetContext(req)
t(ctx)
}
}
+// MiddleCancel wrap a context function as a chi middleware
+func MiddleCancel(f func(ctx *context.Context) goctx.CancelFunc) func(netx http.Handler) http.Handler {
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
+ ctx := context.GetContext(req)
+ cancel := f(ctx)
+ if cancel != nil {
+ defer cancel()
+ }
+ if ctx.Written() {
+ return
+ }
+ next.ServeHTTP(ctx.Resp, ctx.Req)
+ })
+ }
+}
+
// MiddleAPI wrap a context function as a chi middleware
func MiddleAPI(f func(ctx *context.APIContext)) func(netx http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
r.R.Use(t)
case func(*context.Context):
r.R.Use(Middle(t))
+ case func(*context.Context) goctx.CancelFunc:
+ r.R.Use(MiddleCancel(t))
case func(*context.APIContext):
r.R.Use(MiddleAPI(t))
default: