gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package private
  4. import (
  5. "context"
  6. "crypto/tls"
  7. "net"
  8. "net/http"
  9. "os"
  10. "strings"
  11. "time"
  12. "code.gitea.io/gitea/modules/httplib"
  13. "code.gitea.io/gitea/modules/json"
  14. "code.gitea.io/gitea/modules/log"
  15. "code.gitea.io/gitea/modules/proxyprotocol"
  16. "code.gitea.io/gitea/modules/setting"
  17. )
  18. // Response is used for internal request response (for user message and error message)
  19. type Response struct {
  20. Err string `json:"err,omitempty"` // server-side error log message, it won't be exposed to end users
  21. UserMsg string `json:"user_msg,omitempty"` // meaningful error message for end users, it will be shown in git client's output.
  22. }
  23. func getClientIP() string {
  24. sshConnEnv := strings.TrimSpace(os.Getenv("SSH_CONNECTION"))
  25. if len(sshConnEnv) == 0 {
  26. return "127.0.0.1"
  27. }
  28. return strings.Fields(sshConnEnv)[0]
  29. }
  30. func NewInternalRequest(ctx context.Context, url, method string) *httplib.Request {
  31. if setting.InternalToken == "" {
  32. log.Fatal(`The INTERNAL_TOKEN setting is missing from the configuration file: %q.
  33. Ensure you are running in the correct environment or set the correct configuration file with -c.`, setting.CustomConf)
  34. }
  35. if !strings.HasPrefix(url, setting.LocalURL) {
  36. log.Fatal("Invalid internal request URL: %q", url)
  37. }
  38. req := httplib.NewRequest(url, method).
  39. SetContext(ctx).
  40. Header("X-Real-IP", getClientIP()).
  41. Header("X-Gitea-Internal-Auth", "Bearer "+setting.InternalToken).
  42. SetTLSClientConfig(&tls.Config{
  43. InsecureSkipVerify: true,
  44. ServerName: setting.Domain,
  45. })
  46. if setting.Protocol == setting.HTTPUnix {
  47. req.SetTransport(&http.Transport{
  48. DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
  49. var d net.Dialer
  50. conn, err := d.DialContext(ctx, "unix", setting.HTTPAddr)
  51. if err != nil {
  52. return conn, err
  53. }
  54. if setting.LocalUseProxyProtocol {
  55. if err = proxyprotocol.WriteLocalHeader(conn); err != nil {
  56. _ = conn.Close()
  57. return nil, err
  58. }
  59. }
  60. return conn, err
  61. },
  62. })
  63. } else if setting.LocalUseProxyProtocol {
  64. req.SetTransport(&http.Transport{
  65. DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
  66. var d net.Dialer
  67. conn, err := d.DialContext(ctx, network, address)
  68. if err != nil {
  69. return conn, err
  70. }
  71. if err = proxyprotocol.WriteLocalHeader(conn); err != nil {
  72. _ = conn.Close()
  73. return nil, err
  74. }
  75. return conn, err
  76. },
  77. })
  78. }
  79. return req
  80. }
  81. func newInternalRequestAPI(ctx context.Context, url, method string, body ...any) *httplib.Request {
  82. req := NewInternalRequest(ctx, url, method)
  83. if len(body) == 1 {
  84. req.Header("Content-Type", "application/json")
  85. jsonBytes, _ := json.Marshal(body[0])
  86. req.Body(jsonBytes)
  87. } else if len(body) > 1 {
  88. log.Fatal("Too many arguments for newInternalRequestAPI")
  89. }
  90. req.SetTimeout(10*time.Second, 60*time.Second)
  91. return req
  92. }