Skip to content

設定

Config

go
type Config struct {
    Timeouts   TimeoutConfig
    Connection ConnectionConfig
    Security   SecurityConfig
    Retry      RetryConfig
    Middleware MiddlewareConfig
    Defaults   RequestDefaults
}

メイン設定構造体。5 つのサブ設定と Defaults はすべて値型です。DefaultConfig() で安全なデフォルト値を取得し、返された Config のフィールドを直接変更できます。

go
cfg := httpc.DefaultConfig()
cfg.Timeouts.Request = 60 * time.Second
cfg.Retry.MaxRetries = 5
client, err := httpc.New(cfg)

TimeoutConfig

go
type TimeoutConfig struct {
    Request        time.Duration // 総リクエストタイムアウト(リトライ含む)、デフォルト 180s
    Dial           time.Duration // TCP 接続タイムアウト、デフォルト 10s
    TLSHandshake   time.Duration // TLS ハンドシェイクタイムアウト、デフォルト 10s
    ResponseHeader time.Duration // レスポンスヘッダー待機タイムアウト、デフォルト 0(無効、コンテキストタイムアウトに依存)
    IdleConn       time.Duration // アイドル接続維持時間、デフォルト 90s
}
フィールドデフォルト最大
Request180s30min
Dial10s30min
TLSHandshake10s30min
ResponseHeader030min
IdleConn90s30min

0 に設定するとタイムアウトなしになります(本番環境では推奨されません)。

ResponseHeader の設計

ResponseHeader のデフォルトは 0(無効)です。この場合、TimeoutConfig.Request または WithTimeout() が唯一のタイムアウト機構として使用され、WithTimeout() がリクエストの所要時間を完全に制御できます。この設計は AI API やロングポーリングなど、レスポンス時間を延長する必要があるシナリオに適しています。トランスポート層のハードリミットが必要な場合(Slowloris 攻撃の防御など)のみ正の値を設定してください。ただし、これは WithTimeout をオーバーライドすることに注意してください。

ProxyStrategy

go
type ProxyStrategy = proxypool.Strategy

const (
    ProxyStrategyRoundRobin = proxypool.StrategyRoundRobin // ラウンドロビン(デフォルト)
    ProxyStrategyRandom     = proxypool.StrategyRandom     // ランダム
)

プロキシプール選択戦略。

定数説明
ProxyStrategyRoundRobinラウンドロビン(デフォルト)、毎回次のプロキシに進み、リトライ時に自然と別の IP に振られる
ProxyStrategyRandomランダム、健全なプロキシから一様にランダム選択

ConnectionConfig

go
type ConnectionConfig struct {
    MaxIdleConns           int           // グローバル最大アイドル接続数、デフォルト 50
    MaxConnsPerHost        int           // ホストあたりの最大接続数、デフォルト 10
    ProxyURL               string        // プロキシアドレス(例:"http://proxy:8080")
    EnableSystemProxy      bool          // システムプロキシの自動検出、デフォルト false
    ProxyPool              []string      // プロキシサーバーリスト、ローテーション用
    ProxyPoolStrategy      ProxyStrategy // プロキシ選択戦略、デフォルト RoundRobin
    ProxyFailureThreshold  int           // 連続失敗回数のしきい値、0 の場合はデフォルト 3
    ProxyCooldown          time.Duration // サーキットブレーカの冷却時間、0 の場合はデフォルト 30s
    ProxyRotatePerRequest  bool          // 各リクエストで独立してプロキシを強制切り替え、デフォルト false
    ProxyRotateOnStatus    []int         // プロキシローテーションをトリガーする HTTP ステータスコード
    EnableHTTP2            bool          // HTTP/2 を有効化、デフォルト true
    EnableCookies          bool          // Cookie 管理を有効化、デフォルト false
    EnableDoH              bool          // DNS-over-HTTPS を有効化、デフォルト false
    DoHCacheTTL            time.Duration // DoH キャッシュ TTL、デフォルト 5min
    MaxResponseHeaderBytes int64         // レスポンスヘッダーの最大バイト数、デフォルト 0(Go 標準ライブラリのデフォルト 10MB を使用)
}

プロキシプール

ProxyPool はプロキシサーバーのリストを指定し、リクエストは ProxyPoolStrategy に従ってプロキシ間に分散されます。接続失敗(dial/TLS)はパッシブサーキットブレーカをトリガーします:ProxyFailureThreshold 回連続で失敗すると、そのプロキシは一時的にローテーションから外れ、ProxyCooldown 経過後に復旧します(ハーフオープンプローブ)。

優先度:ProxyURL より低く、EnableSystemProxy より高いです。ProxyURLProxyPool を同時に設定した場合、ProxyURL が有効になります(単一プロキシモード)。

ProxyRotateOnStatus はプロキシの切り替えと再試行をトリガーする HTTP ステータスコードを指定します(例:CF/WAF の IP ベースのブロックに対して []int{403})。接続失敗とは異なり、ステータスコードによるローテーションはプロキシをサーキットブレークしません——ブロックはターゲット固有であることが多いためです(あるプロキシがあるサイトでブロックされても、別のサイトでは正常な場合があります)。Retry.MaxRetries > 0 が必要です。

ProxyRotatePerRequest は各独立リクエスト(毎回の Get/Post 呼び出しなど)が異なるプロキシを使用することを保証します。有効でない場合、HTTP 接続の再利用により同一ホストへの連続リクエストが前回のリクエストのプロキシトンネルを再利用し、プロキシプール選択をバイパスしてしまいます。有効化すると、毎回のリクエスト開始時にアイドル接続をクローズし、Transport にプロキシプールを再評価させます——これは少量のオーバーヘッドを追加します(接続再利用なし)が、リクエストごとのローテーションを保証します。ProxyPool の設定が必要です。ProxyURL やプロキシプール未設定には無効です。

ProxyRotatePerRequest と ProxyRotateOnStatus

どちらもプロキシローテーションに使用されますが、トリガー機構が異なります:ProxyRotateOnStatus特定のステータスコードを受信した際にリトライローテーションをトリガーし(受動的、リトライと組み合わせが必要)、ProxyRotatePerRequest毎回のリクエスト開始時に能動的にプロキシを切り替えます(リトライ不要)。同一ホストのスクレイピング/データ収集シナリオでは、ProxyRotatePerRequest により毎回のリクエストの送信元 IP が異なることを保証できます。

go
cfg := httpc.DefaultConfig()
cfg.Connection.ProxyPool = []string{
    "http://proxy1:8080",
    "http://proxy2:8080",
    "http://proxy3:8080",
}
cfg.Connection.ProxyPoolStrategy = httpc.ProxyStrategyRoundRobin
cfg.Connection.ProxyFailureThreshold = 3
cfg.Connection.ProxyCooldown = 30 * time.Second
cfg.Connection.ProxyRotateOnStatus = []int{403}

DNS-over-HTTPS

DoH を有効にすると、DNS 解決遅延の削減と DNS ハイジャックの防止ができます:

go
cfg := httpc.DefaultConfig()
cfg.Connection.EnableDoH = true
cfg.Connection.DoHCacheTTL = 5 * time.Minute

デフォルトの DoH プロバイダー(優先度順):Cloudflare → Google → AliDNS。詳しくは コネクションプール をご覧ください。

SecurityConfig

go
type SecurityConfig struct {
    TLSConfig               *tls.Config           // カスタム TLS 設定
    MinTLSVersion           uint16                // 最低 TLS バージョン、デフォルト TLS 1.2
    MaxTLSVersion           uint16                // 最高 TLS バージョン、デフォルト TLS 1.3
    InsecureSkipVerify      bool                  // 証明書検証をスキップ(テストのみ)
    MaxResponseBodySize     int64                 // レスポンスボディサイズ制限、デフォルト 10MB
    MaxRequestBodySize      int64                 // リクエストボディサイズ制限、デフォルト 0(リクエストボディサイズを制限しない。MaxResponseBodySize とは異なり自動フォールバックなし)
    MaxDecompressedBodySize int64                 // 展開後サイズ制限、デフォルト 100MB
    AllowPrivateIPs         bool                  // プライベート IP を許可、デフォルト false
    SSRFExemptCIDRs         []string              // SSRF 免除 CIDR
    ValidateURL             bool                  // URL 検証、デフォルト true
    ValidateHeaders         bool                  // リクエストヘッダー検証、デフォルト true
    StrictContentLength     bool                  // 厳格な Content-Length、デフォルト true
    CookieSecurity          *CookieSecurityConfig // Cookie セキュリティ検証
    CertificatePinner       CertificatePinner     // 証明書固定(SPKI ハッシュ/公開鍵)、デフォルト nil(無効)
    RedirectWhitelist       []string              // リダイレクトホワイトリストドメイン
}

証明書固定(CertificatePinner)

CertificatePinner は証明書固定を有効にします。サーバーが固定された鍵/証明書を提示しない場合、TLS ハンドシェイクが拒否され、信頼された CA が侵害されていても中間者攻撃を防げます。デフォルトは nil(無効)。以下のコンストラクタで作成します。

コンストラクタ説明
NewSPKIHashPinner(hashes ...string) (CertificatePinner, error)1 つ以上の base64 エンコードされた SPKI SHA-256 ハッシュから作成(最も一般的、鍵のローテーションに対応)
NewPublicKeyPinner(publicKeys ...[]byte) (CertificatePinner, error)DER エンコードされた PKIX 公開鍵から作成(内部で SHA-256 を計算)
NewCertificatePinnerChain(pinners ...CertificatePinner) CertificatePinner複数の pinner を組み合わせ、いずれかが通過すれば受け入れ
go
pinner, err := httpc.NewSPKIHashPinner(
    "YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2fuihg=", // 現在の鍵
    "C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M=", // バックアップ鍵(ローテーション用)
)
if err != nil {
    log.Fatal(err)
}

cfg := httpc.DefaultConfig()
cfg.Security.CertificatePinner = pinner
client, err := httpc.New(cfg)

メンテナンスコスト

証明書固定は、サーバーが証明書を更新した際(Let's Encrypt の更新など)に固定値を同期更新する必要があります。複数のハッシュ(現在用 + バックアップ用)を固定し、更新の仕組みを整えることで、鍵のローテーションによる接続断を防ぐことを推奨します。

SSRF 防護

AllowPrivateIPs のデフォルトは false で、プライベート/予約済み IP(127.0.0.1、10.x、192.168.x など)への接続をブロックします。内部サービスに接続する場合のみ true に設定してください。

SSRF 免除の例

go
cfg := httpc.DefaultConfig()
cfg.Security.SSRFExemptCIDRs = []string{
    "10.0.0.0/8",       // VPC 内部
    "100.64.0.0/10",    // Tailscale
}

RetryConfig

go
type RetryConfig struct {
    MaxRetries    int           // 最大リトライ回数、デフォルト 3
    Delay         time.Duration // 初期リトライ遅延、デフォルト 1s
    BackoffFactor float64       // バックオフ倍数、デフォルト 2.0
    EnableJitter  bool          // ジッターを有効化、デフォルト true
    MaxRetryDelay time.Duration // 最大リトライ遅延上限、デフォルト 30s
    CustomPolicy  RetryPolicy   // カスタムリトライポリシー
}
フィールドデフォルト範囲
MaxRetries30-10
Delay1s0-30min
BackoffFactor2.01.0-10.0
MaxRetryDelay30s0-30min

リトライ遅延の公式:min(Delay * BackoffFactor^attempt + jitter, MaxRetryDelay)

MiddlewareConfig

go
type MiddlewareConfig struct {
    Middlewares []MiddlewareFunc // ミドルウェアリスト、デフォルト nil
}

ミドルウェアチェーンのみを含みます。リクエストのデフォルト値(User-Agent、デフォルトリクエストヘッダー、リダイレクト戦略)は RequestDefaults に移動されました。

RequestDefaults

go
type RequestDefaults struct {
    UserAgent       string            // User-Agent、デフォルト "httpc/1.0"
    Headers         map[string]string // デフォルトリクエストヘッダー、デフォルト空
    FollowRedirects bool              // リダイレクトに追従、デフォルト true
    MaxRedirects    int               // 最大リダイレクト回数、デフォルト 10
}

リクエストデフォルト値の正規の場所:User-Agent、デフォルトリクエストヘッダー、リダイレクト戦略。DefaultConfig() で適切なデフォルト値を取得し、必要に応じて変更します。

go
cfg := httpc.DefaultConfig()
cfg.Defaults.UserAgent = "myapp/2.0"
cfg.Defaults.Headers = map[string]string{"Accept": "application/json"}
cfg.Defaults.MaxRedirects = 5

設定プリセット

DefaultConfig

go
func DefaultConfig() Config

安全なデフォルト設定。SSRF 防護がデフォルトで有効です。

SecureConfig

go
func SecureConfig() Config

セキュリティ優先設定。短いタイムアウト、自動リダイレクト無効、厳格な SSRF 防護。

設定項目
Request タイムアウト15s
Dial タイムアウト5s
TLSHandshake タイムアウト5s
ResponseHeader タイムアウト10s(Slowloris 防御)
IdleConn タイムアウト30s
MaxIdleConns20
MaxConnsPerHost5
MaxResponseBodySize5MB
MaxRetries1
Delay2s
EnableJittertrue
FollowRedirectsfalse

PerformanceConfig

go
func PerformanceConfig() Config

高スループット設定。大規模コネクションプール、長いタイムアウト、セキュリティ検証を維持。

TIP

PerformanceConfig は安全性を確保するため ValidateURLValidateHeaders を有効にしています。信頼できる環境で最大パフォーマンスが必要な場合は、手動で cfg.Security.ValidateURL = false に設定できますが、セキュリティリスク(インジェクション攻撃、SSRF)に注意してください。

設定項目
Request タイムアウト60s
Dial タイムアウト15s
TLSHandshake タイムアウト15s
ResponseHeader タイムアウト0(無効、Request タイムアウトを使用)
IdleConn タイムアウト120s
MaxIdleConns100
MaxConnsPerHost20
EnableCookiestrue
MaxResponseBodySize50MB
StrictContentLengthfalse
ValidateURLtrue
ValidateHeaderstrue
Delay500ms
BackoffFactor1.5
EnableJittertrue

TestingConfig

go
func TestingConfig() Config

テスト環境設定。セキュリティチェック無効、短いタイムアウト。

設定項目
Dial タイムアウト5s
TLSHandshake タイムアウト5s
ResponseHeader タイムアウト0(無効、Request タイムアウトを使用)
IdleConn タイムアウト30s
MaxIdleConns10
MaxConnsPerHost5
EnableHTTP2false
EnableCookiestrue
InsecureSkipVerifytrue
AllowPrivateIPstrue
ValidateURLfalse
ValidateHeadersfalse
MaxRetries1
Delay100ms
EnableJitterfalse
UserAgenthttpc-test/1.0

DANGER

この設定は TLS 検証と SSRF 防護を無効にします。テストのみに使用してください。テスト以外の環境で使用するとセキュリティ警告が出力されます(詳しくは セキュリティ警告の出力 を参照)。

MinimalConfig

go
func MinimalConfig() Config

軽量設定。リトライとリダイレクト無効、最小コネクションプール。

設定項目
Dial タイムアウト5s
TLSHandshake タイムアウト5s
ResponseHeader タイムアウト0(無効、Request タイムアウトを使用)
IdleConn タイムアウト30s
MaxIdleConns10
MaxConnsPerHost2
MaxResponseBodySize1MB
MaxRetries0
Delay0
BackoffFactor1.0
EnableJitterfalse
FollowRedirectsfalse

セキュリティ警告の出力

SetSecurityWarnOutput

go
func SetSecurityWarnOutput(w io.Writer)

セキュリティ警告の出力先をリダイレクトします。TestingConfig() を使用した場合、または SecurityConfig.InsecureSkipVerifyConfig.Security)を true に設定した場合、httpc はこの writer に [SECURITY WARNING] レベルの警告を出力します(警告の種類ごとにプロセス単位で最大 1 回まで出力)。デフォルトの出力先は os.Stderr です。io.Discard を渡すことで警告を完全に抑制でき、テスト時や安全性が確認された内部シナリオでのサイレント実行に便利です。

go
// テストでセキュリティ警告を抑制
httpc.SetSecurityWarnOutput(io.Discard)
cfg := httpc.TestingConfig()

影響範囲

この設定はプロセスレベルのグローバル状態であり、以降に作成されるすべてのクライアントに影響します。TestingConfigInsecureSkipVerify の 2 種類の警告はそれぞれ独立してカウントされます(互いのトリガーに影響しません)が、同じ出力 writer を共有します。

検証

ValidateConfig

go
func ValidateConfig(cfg *Config) error

設定の有効性を検証します。New() 内部で自動的に呼び出されますが、明示的に呼び出すことも可能です。

go
cfg := httpc.DefaultConfig()
cfg.Retry.MaxRetries = 100 // 範囲外

if err := httpc.ValidateConfig(&cfg); err != nil {
    log.Fatal(err) // invalid retry configuration: Retry.MaxRetries must be 0-10, got 100
}

Config.String

go
func (c *Config) String() string

安全な文字列表現を返します。ProxyURL の認証情報はマスクされ、TLSConfig は <configured> または <default> と表示され、Headers は出力されません。

go
cfg := httpc.DefaultConfig()
fmt.Println(cfg.String())
// Config{Timeouts:{Request: 3m0s, ...}, Security:{TLSConfig: <default>, ...}}

CookieSecurityConfig

go
type CookieSecurityConfig struct {
    RequireSecure                bool
    RequireHttpOnly              bool
    RequireSameSite              string
    AllowSameSiteNone            bool
    RequireSecureForSameSiteNone bool
}

Cookie セキュリティ属性の検証設定。

フィールドタイプ説明
RequireSecureboolCookie に Secure 属性の設定を要求
RequireHttpOnlyboolCookie に HttpOnly 属性の設定を要求
RequireSameSitestring要求する SameSite 値(例:"Strict""Lax")。空文字列はチェックなし
AllowSameSiteNoneboolSameSite=None を許可するかどうか
RequireSecureForSameSiteNoneboolSameSite=None の場合に Secure 属性を要求(デフォルト true

DefaultCookieSecurityConfig

go
func DefaultCookieSecurityConfig() *CookieSecurityConfig

デフォルトの Cookie セキュリティ設定。Secure/HttpOnly/SameSite 属性は要求しませんが、SameSite=None の Cookie には Secure の設定を強制します。

StrictCookieSecurityConfig

go
func StrictCookieSecurityConfig() *CookieSecurityConfig

厳格な Cookie セキュリティ設定。Secure、HttpOnly、SameSite=Strict を要求します。

go
cfg := httpc.DefaultConfig()
cfg.Security.CookieSecurity = httpc.StrictCookieSecurityConfig()