transport

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 23, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package transport provides scoped, cancellable Gitea API requests.

Index

Constants

This section is empty.

Variables

View Source
var ErrTimeout error = responseTimeoutError{}

ErrTimeout is the cause of a request that ran out of the response timeout: whose answer did not start, whose body stopped going out, or whose response stalled. It matches context.DeadlineExceeded, so that it exits like a timeout, but tells the request apart from an operation whose own deadline, such as a --timeout, expired.

View Source
var UserAgent = "gt/" + version.Current() + " (" + runtime.GOOS + "/" + runtime.GOARCH + ")"

UserAgent identifies gt to instances, proxies, and server logs.

Functions

func CaptureErrors

func CaptureErrors(ctx context.Context) (context.Context, func() *APIError)

CaptureErrors returns a context under which API clients record the sanitized error of each response outside 2xx, and a function returning the last one recorded.

func ConfiguredHeaders

func ConfiguredHeaders(req *http.Request) []string

ConfiguredHeaders returns the names of the headers the instance's configuration added to req, such as the request of a response, whose values may be secrets read from the environment.

func LoadClientCertificate

func LoadClientCertificate(certFile, keyFile string) (*tls.Certificate, error)

LoadClientCertificate loads the PEM certificate in certFile with the key in keyFile, or in certFile when keyFile is empty.

func RedactHeader

func RedactHeader(name, value string) string

RedactHeader returns the value of a response header named name with the URLs it carries, such as a Location of signed storage or the pages of a Link header, redacted like the URLs --debug logs. Other headers are returned unchanged.

func RedactSecrets

func RedactSecrets(ctx context.Context, message string) string

RedactSecrets replaces each secret marked on ctx in message, as is or escaped for a URL query, path or userinfo, and the password of each URL with [REDACTED].

func RequestError

func RequestError(ctx context.Context, action string, err error) error

RequestError keeps the network or TLS cause of a failed request. The cause of a *url.Error omits the request URL, whose query may carry secrets.

func ResponseError

func ResponseError(ctx context.Context, resp *http.Response, err error) error

ResponseError reports a failure to read the body of resp, such as a connection that stalled or dropped, as a *RequestFailure, like a request that received no answer.

func UnboundedResponse

func UnboundedResponse(ctx context.Context) context.Context

UnboundedResponse marks ctx for requests whose answer starts only when a long operation is done, such as a synchronous migration, so that no response timeout applies to them.

func WithSecrets

func WithSecrets(ctx context.Context, values ...string) context.Context

WithSecrets marks ctx with secrets that a request carries in its body, such as source credentials of a migration, so that whatever echoes them is redacted with RedactSecrets.

Types

type APIError

type APIError struct {
	Status                    int
	Method, Endpoint, Message string
	// Instance is the installation URL the failed request was sent to, when it was recorded
	// from a request.
	Instance string
	// Storage is the host a download was redirected to, such as signed object storage, when
	// that host rather than the instance answered.
	Storage string
	// Moved is the OWNER/REPO a repository was renamed or transferred to, when the instance
	// redirected a request that changes it and the redirect was not followed.
	Moved string
}

APIError reports request failure without including credentials or raw response bodies. Message holds only the sanitized "message" field of a JSON error body.

func (*APIError) Error

func (e *APIError) Error() string

type Client

type Client struct {
	BaseURL string
	Token   string
	// Sudo asks the instance to perform requests as this user (administrators only).
	Sudo    string
	Signer  RequestSigner
	HTTP    *http.Client
	Retries int
}

Client binds HTTP requests to one instance and credential.

func New

func New(instance, token string, insecure bool) *Client

New constructs an instance-scoped client. Its HTTP client follows no redirects itself; API requests follow only those within the instance API. Only connection setup is bounded here; WithResponseTimeout bounds the wait for an answer, which a synchronous migration may need minutes to start. insecure skips certificate verification for the instance's host only; other hosts, such as the storage a download redirects to, are still verified.

func (*Client) API

func (c *Client) API() *http.Client

API returns an HTTP client for requests to this instance. It attaches the credential and Sudo header to every attempt, retries only body-free reads, follows redirects (a renamed or transferred repository) only within this instance's API, and records the sanitized error of a failed response for CaptureErrors.

func (*Client) Debug

func (c *Client) Debug(w io.Writer) *Client

Debug returns a copy of c that logs the method, redacted URL, status, and duration of each request to w, plus the sanitized server message of a failed response, with the secrets marked by WithSecrets redacted. Headers and bodies are never logged.

func (*Client) Do

func (c *Client) Do(ctx context.Context, method, endpoint string, body io.Reader, headers http.Header) (*http.Response, error)

Do executes a cancellable request, retrying only safe body-free reads. A response outside 2xx is closed and returned as an *APIError.

func (*Client) Download

func (c *Client) Download(ctx context.Context, raw string) (*http.Response, error)

Download opens an instance-scoped file URL, following redirects only within the instance API.

func (*Client) DownloadSigned

func (c *Client) DownloadSigned(ctx context.Context, raw string) (*http.Response, error)

DownloadSigned opens an instance-scoped file URL and follows at most one redirect without credentials, such as Gitea's redirect to signed object-storage URLs. The redirect target may be another host, but must use HTTPS or the instance's scheme. Automatic redirects remain disabled, including on an injected HTTP client.

func (*Client) Send

func (c *Client) Send(ctx context.Context, method, endpoint string, body io.Reader, headers http.Header) (*http.Response, error)

Send is Do without converting responses outside 2xx into errors.

func (*Client) URL

func (c *Client) URL(endpoint string) (string, error)

URL accepts only endpoints within the selected installation API.

func (*Client) WithClientCertificate

func (c *Client) WithClientCertificate(certFile, keyFile string) *Client

WithClientCertificate returns a client that presents the PEM certificate and key in certFile and keyFile, or in certFile alone, when the instance asks for one in the TLS handshake; other hosts never see it. The files are read at the first handshake, so an unreadable pair fails the request that needs it. A client whose transport cannot present one fails every request instead.

func (*Client) WithHeaders

func (c *Client) WithHeaders(headers http.Header) *Client

WithHeaders returns a client that adds headers to every request to its instance.

func (*Client) WithResponseTimeout

func (c *Client) WithResponseTimeout(timeout time.Duration) *Client

WithResponseTimeout returns a client whose requests fail when the instance takes longer than timeout to start answering once the request has been sent, or, while a request body is sent, to read more of it, or, where the system tells, to receive more of what the connection still holds of it, or, once it answers, to send more of the response body; neither a slow but progressing upload nor a slow but progressing body, such as a download, is cut off. Zero waits as long as it takes.

type ReplayableBody

type ReplayableBody struct {
	io.Reader
	// contains filtered or unexported fields
}

ReplayableBody is a request body that can be read again from the start, so that signing can hash a large body, such as an upload, as it reads it instead of buffering it.

func Replayable

func Replayable(open func() io.Reader) *ReplayableBody

Replayable returns the body that open reads from the start each time it is called.

type RequestFailure

type RequestFailure struct {
	// Action names what failed, such as "API request failed".
	Action string
	// Server is the scheme and host the request was sent to, without path or query.
	Server string
	// Err is the network or TLS cause.
	Err error
}

RequestFailure reports a request that received no HTTP response, such as a refused connection or an untrusted certificate, or whose response broke off.

func (*RequestFailure) Error

func (e *RequestFailure) Error() string

func (*RequestFailure) Unwrap

func (e *RequestFailure) Unwrap() error

type RequestSigner

type RequestSigner interface {
	SignRequest(r *http.Request, contents []byte) error
}

RequestSigner attaches HTTP signature headers for SSH/HTTPSign authentication. contents is the body to digest, or nil when there is none or r already carries its SHA-512 Digest header.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL