2021-01-26 23:36:53 +08:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2022-11-27 13:20:29 -05:00
// SPDX-License-Identifier: MIT
2021-01-26 23:36:53 +08:00
package context
import (
"context"
2022-01-19 23:26:57 +00:00
"fmt"
2021-01-26 23:36:53 +08:00
"net/http"
2022-01-19 23:26:57 +00:00
"time"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/process"
2021-01-26 23:36:53 +08:00
)
// PrivateContext represents a context for private routes
type PrivateContext struct {
2023-05-21 09:50:53 +08:00
* Base
2022-01-19 23:26:57 +00:00
Override context . Context
2023-05-21 09:50:53 +08:00
Repo * Repository
2022-01-19 23:26:57 +00:00
}
// Deadline is part of the interface for context.Context and we pass this to the request context
func ( ctx * PrivateContext ) Deadline ( ) ( deadline time . Time , ok bool ) {
if ctx . Override != nil {
return ctx . Override . Deadline ( )
}
2023-05-21 09:50:53 +08:00
return ctx . Base . Deadline ( )
2022-01-19 23:26:57 +00:00
}
// Done is part of the interface for context.Context and we pass this to the request context
func ( ctx * PrivateContext ) Done ( ) <- chan struct { } {
if ctx . Override != nil {
return ctx . Override . Done ( )
}
2023-05-21 09:50:53 +08:00
return ctx . Base . Done ( )
2022-01-19 23:26:57 +00:00
}
// Err is part of the interface for context.Context and we pass this to the request context
func ( ctx * PrivateContext ) Err ( ) error {
if ctx . Override != nil {
return ctx . Override . Err ( )
}
2023-05-21 09:50:53 +08:00
return ctx . Base . Err ( )
2021-01-26 23:36:53 +08:00
}
2022-01-20 18:46:10 +01:00
var privateContextKey interface { } = "default_private_context"
2021-01-26 23:36:53 +08:00
// GetPrivateContext returns a context for Private routes
func GetPrivateContext ( req * http . Request ) * PrivateContext {
return req . Context ( ) . Value ( privateContextKey ) . ( * PrivateContext )
}
2021-01-29 23:35:30 +08:00
// PrivateContexter returns apicontext as middleware
2021-01-26 23:36:53 +08:00
func PrivateContexter ( ) func ( http . Handler ) http . Handler {
return func ( next http . Handler ) http . Handler {
return http . HandlerFunc ( func ( w http . ResponseWriter , req * http . Request ) {
2023-05-21 09:50:53 +08:00
base , baseCleanUp := NewBaseContext ( w , req )
ctx := & PrivateContext { Base : base }
defer baseCleanUp ( )
ctx . Base . AppendContextValue ( privateContextKey , ctx )
2022-05-05 22:13:23 +08:00
2021-01-26 23:36:53 +08:00
next . ServeHTTP ( ctx . Resp , ctx . Req )
} )
}
}
2022-01-19 23:26:57 +00:00
// 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 ( ctx * PrivateContext ) ( cancel context . CancelFunc ) {
// 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
2022-03-31 18:01:43 +01:00
ctx . Override , _ , cancel = process . GetManager ( ) . AddTypedContext ( graceful . GetManager ( ) . HammerContext ( ) , fmt . Sprintf ( "PrivateContext: %s" , ctx . Req . RequestURI ) , process . RequestProcessType , true )
2022-06-20 12:02:49 +02:00
return cancel
2022-01-19 23:26:57 +00:00
}