gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package context
  4. import (
  5. "context"
  6. "net/http"
  7. "time"
  8. "code.gitea.io/gitea/modules/graceful"
  9. "code.gitea.io/gitea/modules/process"
  10. "code.gitea.io/gitea/modules/web"
  11. web_types "code.gitea.io/gitea/modules/web/types"
  12. )
  13. // PrivateContext represents a context for private routes
  14. type PrivateContext struct {
  15. *Base
  16. Override context.Context
  17. Repo *Repository
  18. }
  19. func init() {
  20. web.RegisterResponseStatusProvider[*PrivateContext](func(req *http.Request) web_types.ResponseStatusProvider {
  21. return req.Context().Value(privateContextKey).(*PrivateContext)
  22. })
  23. }
  24. func (ctx *PrivateContext) Deadline() (deadline time.Time, ok bool) {
  25. if ctx.Override != nil {
  26. return ctx.Override.Deadline()
  27. }
  28. return ctx.Base.Deadline()
  29. }
  30. func (ctx *PrivateContext) Done() <-chan struct{} {
  31. if ctx.Override != nil {
  32. return ctx.Override.Done()
  33. }
  34. return ctx.Base.Done()
  35. }
  36. func (ctx *PrivateContext) Err() error {
  37. if ctx.Override != nil {
  38. return ctx.Override.Err()
  39. }
  40. return ctx.Base.Err()
  41. }
  42. type privateContextKeyType struct{}
  43. var privateContextKey privateContextKeyType
  44. func GetPrivateContext(req *http.Request) *PrivateContext {
  45. return req.Context().Value(privateContextKey).(*PrivateContext)
  46. }
  47. func PrivateContexter() func(http.Handler) http.Handler {
  48. return func(next http.Handler) http.Handler {
  49. return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
  50. base := NewBaseContext(w, req)
  51. ctx := &PrivateContext{Base: base}
  52. ctx.SetContextValue(privateContextKey, ctx)
  53. next.ServeHTTP(ctx.Resp, ctx.Req)
  54. })
  55. }
  56. }
  57. // OverrideContext overrides the underlying request context for Done() etc.
  58. // This function should be used when there is a need for work to continue even if the request has been cancelled.
  59. // Primarily this affects hook/post-receive and hook/proc-receive both of which need to continue working even if
  60. // the underlying request has timed out from the ssh/http push
  61. func OverrideContext() func(http.Handler) http.Handler {
  62. return func(next http.Handler) http.Handler {
  63. return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
  64. // 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
  65. ctx := GetPrivateContext(req)
  66. var finished func()
  67. ctx.Override, _, finished = process.GetManager().AddTypedContext(graceful.GetManager().HammerContext(), "PrivateContext: "+ctx.Req.RequestURI, process.RequestProcessType, true)
  68. defer finished()
  69. next.ServeHTTP(ctx.Resp, ctx.Req)
  70. })
  71. }
  72. }