gitea源码

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package context
  4. import (
  5. "net/http"
  6. web_types "code.gitea.io/gitea/modules/web/types"
  7. )
  8. // ResponseWriter represents a response writer for HTTP
  9. type ResponseWriter interface {
  10. http.ResponseWriter // provides Header/Write/WriteHeader
  11. http.Flusher // provides Flush
  12. web_types.ResponseStatusProvider // provides WrittenStatus
  13. Before(fn func(ResponseWriter))
  14. WrittenSize() int
  15. }
  16. var _ ResponseWriter = (*Response)(nil)
  17. // Response represents a response
  18. type Response struct {
  19. http.ResponseWriter
  20. written int
  21. status int
  22. beforeFuncs []func(ResponseWriter)
  23. beforeExecuted bool
  24. }
  25. // Write writes bytes to HTTP endpoint
  26. func (r *Response) Write(bs []byte) (int, error) {
  27. if !r.beforeExecuted {
  28. for _, before := range r.beforeFuncs {
  29. before(r)
  30. }
  31. r.beforeExecuted = true
  32. }
  33. size, err := r.ResponseWriter.Write(bs)
  34. r.written += size
  35. if err != nil {
  36. return size, err
  37. }
  38. if r.status == 0 {
  39. r.status = http.StatusOK
  40. }
  41. return size, nil
  42. }
  43. func (r *Response) WrittenSize() int {
  44. return r.written
  45. }
  46. // WriteHeader write status code
  47. func (r *Response) WriteHeader(statusCode int) {
  48. if !r.beforeExecuted {
  49. for _, before := range r.beforeFuncs {
  50. before(r)
  51. }
  52. r.beforeExecuted = true
  53. }
  54. if r.status == 0 {
  55. r.status = statusCode
  56. r.ResponseWriter.WriteHeader(statusCode)
  57. }
  58. }
  59. // Flush flushes cached data
  60. func (r *Response) Flush() {
  61. if f, ok := r.ResponseWriter.(http.Flusher); ok {
  62. f.Flush()
  63. }
  64. }
  65. // WrittenStatus returned status code written
  66. func (r *Response) WrittenStatus() int {
  67. return r.status
  68. }
  69. // Before allows for a function to be called before the ResponseWriter has been written to. This is
  70. // useful for setting headers or any other operations that must happen before a response has been written.
  71. func (r *Response) Before(fn func(ResponseWriter)) {
  72. r.beforeFuncs = append(r.beforeFuncs, fn)
  73. }
  74. func WrapResponseWriter(resp http.ResponseWriter) *Response {
  75. if v, ok := resp.(*Response); ok {
  76. return v
  77. }
  78. return &Response{ResponseWriter: resp}
  79. }