Live video on the AT Protocol
1package aqhttp
2
3import (
4 "context"
5 "net/http"
6 "os"
7 "strings"
8 "time"
9)
10
11var UserAgent string = "streamplace/unknown"
12
13// Client is the default HTTP client with SSRF protection.
14// Uses DNS-over-HTTPS to validate destination IPs and blocks private/bogon ranges.
15// For trusted infrastructure endpoints, use TrustedClient instead.
16var Client http.Client
17
18// TrustedClient is an HTTP client without SSRF protection.
19// Use this only for trusted infrastructure endpoints (e.g., livepeer.com)
20// where the validation overhead is problematic.
21var TrustedClient http.Client
22
23type ClientOptions struct {
24 OverrideInTest bool
25}
26
27var defaultClientOptions = ClientOptions{
28 OverrideInTest: true,
29}
30
31func init() {
32 // Initialize the trusted client first.
33 TrustedClient = http.Client{
34 Transport: NewTrustedTransport(),
35 Timeout: 30 * time.Second,
36 }
37
38 // Initialize the default (untrusted) client which performs SSRF checks.
39 Client = http.Client{
40 Transport: NewUntrustedTransport(),
41 CheckRedirect: func(req *http.Request, via []*http.Request) error {
42 return http.ErrUseLastResponse
43 },
44 Timeout: 30 * time.Second,
45 }
46
47 // When running under `go test` the test binary name typically ends with ".test".
48 // In that case, use the trusted client to avoid SSRF blocking for localhost tests.
49 if defaultClientOptions.OverrideInTest && len(os.Args) > 0 && strings.HasSuffix(os.Args[0], ".test") {
50 Client = TrustedClient
51 }
52}
53
54// Do executes an HTTP request with SSRF protection (secure by default).
55// Most callsites should use this function.
56func Do(ctx context.Context, req *http.Request) (*http.Response, error) {
57 return Client.Do(req.WithContext(ctx))
58}
59
60// DoTrusted executes an HTTP request without SSRF protection.
61// Use this only for trusted infrastructure endpoints.
62func DoTrusted(ctx context.Context, req *http.Request) (*http.Response, error) {
63 return TrustedClient.Do(req.WithContext(ctx))
64}