code.gitea.io/gitea@v1.22.3/modules/private/internal.go (about)

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