| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // Copyright 2020 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package context
-
- import (
- "context"
- "net/http"
- "time"
-
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/web"
- web_types "code.gitea.io/gitea/modules/web/types"
- )
-
- // PrivateContext represents a context for private routes
- type PrivateContext struct {
- *Base
- Override context.Context
-
- Repo *Repository
- }
-
- func init() {
- web.RegisterResponseStatusProvider[*PrivateContext](func(req *http.Request) web_types.ResponseStatusProvider {
- return req.Context().Value(privateContextKey).(*PrivateContext)
- })
- }
-
- func (ctx *PrivateContext) Deadline() (deadline time.Time, ok bool) {
- if ctx.Override != nil {
- return ctx.Override.Deadline()
- }
- return ctx.Base.Deadline()
- }
-
- func (ctx *PrivateContext) Done() <-chan struct{} {
- if ctx.Override != nil {
- return ctx.Override.Done()
- }
- return ctx.Base.Done()
- }
-
- func (ctx *PrivateContext) Err() error {
- if ctx.Override != nil {
- return ctx.Override.Err()
- }
- return ctx.Base.Err()
- }
-
- type privateContextKeyType struct{}
-
- var privateContextKey privateContextKeyType
-
- func GetPrivateContext(req *http.Request) *PrivateContext {
- return req.Context().Value(privateContextKey).(*PrivateContext)
- }
-
- func PrivateContexter() func(http.Handler) http.Handler {
- return func(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- base := NewBaseContext(w, req)
- ctx := &PrivateContext{Base: base}
- ctx.SetContextValue(privateContextKey, ctx)
- next.ServeHTTP(ctx.Resp, ctx.Req)
- })
- }
- }
-
- // OverrideContext overrides the underlying request context for Done() etc.
- // This function should be used when there is a need for work to continue even if the request has been cancelled.
- // Primarily this affects hook/post-receive and hook/proc-receive both of which need to continue working even if
- // the underlying request has timed out from the ssh/http push
- func OverrideContext() func(http.Handler) http.Handler {
- return func(next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
- // We now need to override the request context as the base for our work because even if the request is cancelled we have to continue this work
- ctx := GetPrivateContext(req)
- var finished func()
- ctx.Override, _, finished = process.GetManager().AddTypedContext(graceful.GetManager().HammerContext(), "PrivateContext: "+ctx.Req.RequestURI, process.RequestProcessType, true)
- defer finished()
- next.ServeHTTP(ctx.Resp, ctx.Req)
- })
- }
- }
|