インターフェース定義
Client
type Client interface {
Doer
// HTTP メソッド
Get(url string, options ...RequestOption) (*Result, error)
Post(url string, options ...RequestOption) (*Result, error)
Put(url string, options ...RequestOption) (*Result, error)
Patch(url string, options ...RequestOption) (*Result, error)
Delete(url string, options ...RequestOption) (*Result, error)
Head(url string, options ...RequestOption) (*Result, error)
Options(url string, options ...RequestOption) (*Result, error)
// ファイルダウンロード
Download(ctx context.Context, url string, cfg *DownloadConfig, options ...RequestOption) (*DownloadResult, error)
// ライフサイクル
Close() error
}メインクライアントインターフェース。New() で作成します。詳しくは パッケージ関数とクライアントメソッド をご覧ください。
Doer
type Doer interface {
Request(ctx context.Context, method, url string, options ...RequestOption) (*Result, error)
}最小インターフェース。コアの Request メソッドのみを含みます。カスタム実装に適しています。
type MyDoer struct{}
func (d *MyDoer) Request(ctx context.Context, method, url string, options ...httpc.RequestOption) (*httpc.Result, error) {
// カスタム実装
return nil, nil
}DomainClienter
type DomainClienter interface {
Client
// URL アクセス
URL() string
Domain() string
// セッションヘッダー管理
SetHeader(key, value string) error
SetHeaders(headers map[string]string) error
DeleteHeader(key string)
ClearHeaders()
GetHeaders() map[string]string
// セッション Cookie 管理
SetCookie(cookie *http.Cookie) error
SetCookies(cookies []*http.Cookie) error
DeleteCookie(name string)
ClearCookies()
GetCookies() []*http.Cookie
GetCookie(name string) *http.Cookie
// セッションアクセス
Session() *SessionManager
}ドメインスコープクライアント。Cookie とヘッダーを自動管理します。詳しくは ドメインクライアント と セッション管理 をご覧ください。
RetryPolicy
type RetryPolicy interface {
ShouldRetry(resp ResponseReader, err error, attempt int) bool
GetDelay(attempt int) time.Duration
MaxRetries() int
}カスタムリトライポリシーインターフェース。
| メソッド | 説明 |
|---|---|
ShouldRetry(resp, err, attempt) | リトライするかどうかを判定。attempt は 0 から開始 |
GetDelay(attempt) | 次回リトライまでの待機時間を返す |
MaxRetries() | 最大リトライ回数を返す |
内部タイプの制限
ShouldRetry の resp パラメータのタイプ ResponseReader は内部インターフェース(internal/types パッケージに配置)であり、外部コードからは直接参照できません。そのため、RetryPolicy は同じモジュール内でのみ実装可能です。ほとんどのシナリオでは RetryConfig 設定と WithMaxRetries オプションでリトライ要件を満たせます。カスタムポリシーが必要な場合は、プロジェクト内のパッケージで RetryPolicy インターフェースを実装してください。
以下の例は RetryPolicy の実装パターンを示しています。ResponseReader は内部タイプであるため、このコードは httpc モジュール内部でのみコンパイル可能です:
// 注意:ResponseReader は内部タイプ(internal/types パッケージ)です。
// このコードは httpc モジュール外部ではコンパイルできません。
// ほとんどのユーザーは RetryConfig と WithMaxRetries でリトライを設定してください。
type MyRetryPolicy struct {
maxRetries int
}
func (p *MyRetryPolicy) ShouldRetry(resp ResponseReader, err error, attempt int) bool {
if attempt >= p.maxRetries {
return false
}
if err != nil {
return true
}
return resp.StatusCode() >= 500
}
func (p *MyRetryPolicy) GetDelay(attempt int) time.Duration {
return time.Second * time.Duration(1<<attempt)
}
func (p *MyRetryPolicy) MaxRetries() int {
return p.maxRetries
}コアタイプ
RequestMutator
type RequestMutator interface {
// 読み取りメソッド
Method() string
URL() string
Headers() map[string]string
QueryParams() map[string]any
Body() any
Timeout() time.Duration
MaxRetries() int
Context() context.Context
Cookies() []http.Cookie
FollowRedirects() *bool
MaxRedirects() *int
StreamBody() bool
// 書き込みメソッド
SetMethod(string)
SetURL(string)
SetHeaders(map[string]string)
SetHeader(key, value string)
SetQueryParams(map[string]any)
SetBody(any)
SetTimeout(time.Duration)
SetMaxRetries(int)
SetContext(context.Context)
SetCookies([]http.Cookie)
SetFollowRedirects(*bool)
SetMaxRedirects(*int)
SetStreamBody(bool)
}ミドルウェアで使用され、リクエストの読み書きアクセスを提供します。内部インターフェース RequestReader と RequestWriter で構成されています。完全なメソッド契約と読み書きの例は リクエストとレスポンスミューテータ を参照してください。
ResponseMutator
type ResponseMutator interface {
// 読み取りメソッド
StatusCode() int
Status() string
Proto() string
Headers() http.Header
Body() string
RawBody() []byte
ContentLength() int64
Duration() time.Duration
Attempts() int
Cookies() []*http.Cookie
RedirectChain() []string
RedirectCount() int
RequestHeaders() http.Header
RequestURL() string
RequestMethod() string
// 書き込みメソッド
SetStatusCode(int)
SetStatus(string)
SetProto(string)
SetHeaders(http.Header)
SetBody(string)
SetRawBody([]byte)
SetContentLength(int64)
SetDuration(time.Duration)
SetAttempts(int)
SetCookies([]*http.Cookie)
SetRedirectChain([]string)
SetRedirectCount(int)
SetRequestHeaders(http.Header)
SetRequestURL(string)
SetRequestMethod(string)
SetHeader(key string, values ...string)
}ミドルウェアで使用され、レスポンスの読み書きアクセスを提供します。内部インターフェース ResponseReader と ResponseWriter で構成されています。完全なメソッド契約は リクエストとレスポンスミューテータ を参照してください。
Handler
type Handler func(ctx context.Context, req RequestMutator) (ResponseMutator, error)リクエスト処理関数のシグネチャ。
MiddlewareFunc
type MiddlewareFunc func(Handler) Handlerミドルウェア関数のシグネチャ。次の Handler を受け取り、ラップされた Handler を返します。
証明書ピンニング
証明書ピンニング(Certificate Pinning)は、TLS ハンドシェイク時にサーバー証明書が事前に固定された公開鍵/証明書と一致するかを検証します。信頼された CA が侵害されていてもハンドシェイクは拒否されるため、中間者攻撃を防げます。
CertificatePinner
type CertificatePinner = security.CertificatePinner証明書ピンナーインターフェース。以下のコンストラクタで作成後、SecurityConfig.CertificatePinner フィールド(Config.Security 経由でアクセス)に代入します。
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)TIP
Pinner の実装は並行安全であり、同じ Config から作成された複数のクライアントで共有できます(ディープコピー時は参照渡しされ、複製されません)。上級者はこのインターフェースを直接実装して、カスタムピンニング戦略(公開鍵ではなく完全な証明書を固定するなど)をサポートすることも可能です。
NewSPKIHashPinner
func NewSPKIHashPinner(hashes ...string) (CertificatePinner, error)1 つ以上の base64 エンコードされた SHA-256 ハッシュ値(DER エンコードされた SubjectPublicKeyInfo/SPKI に対する)から証明書ピンナーを作成します。これは最も一般的なピンニング形式(HPKP が採用)であり、推奨されるアプローチです。
複数のハッシュを渡すことで鍵のローテーションに対応できます——対向側の公開鍵が固定されたハッシュのいずれか 1 つに一致すれば、ハンドシェイクは成功します。
以下のコマンドで証明書からハッシュを生成します:
openssl x509 -in cert.pem -pubkey -noout | openssl pkey -pubin -outform der \
| openssl dgst -sha256 -binary | openssl enc -base64有効なハッシュが提供されない、またはハッシュが正当な base64 でない場合、エラーを返します。
NewPublicKeyPinner
func NewPublicKeyPinner(publicKeys ...[]byte) (CertificatePinner, error)1 つ以上の DER エンコードされた PKIX 公開鍵(x509.MarshalPKIXPublicKey が返すもの)から証明書ピンナーを作成します。内部で各公開鍵の SHA-256 ハッシュを計算します。すでに元の公開鍵バイトを保持している場合は、NewSPKIHashPinner よりも便利な選択肢です。
有効な公開鍵が提供されない場合、エラーを返します。
NewCertificatePinnerChain
func NewCertificatePinnerChain(pinners ...CertificatePinner) CertificatePinner複数のピンナーを 1 つに組み合わせます。ラップされたピンナーのいずれか 1 つが証明書を受け入れれば、証明書は受け入れられます。複数のピンニング戦略を同時にサポートする場合や、異なるコンストラクタで構築したローテーション用鍵を組み合わせる場合に使用します。
ゼロ引数の挙動:すべての証明書を許可
引数を渡さない場合、空のチェーンを返します。このチェーンは一切の証明書検証を行いません(検証ロジックが直接 nil を返します)。つまりすべての証明書を受け入れます(証明書ピンニングが無効化された状態 = fail-open)。これは「ピンナーがない=すべて拒否」という直感と逆の挙動です(ソースコード internal/security/certpin.go のコメント "No pinners means no pinning" を参照)。常に少なくとも 1 つの有効な pinner を渡してください。ゼロ引数の挙動に依存しないでください。
さらに詳しく
証明書ピンニングの完全なガイド(ハッシュ生成、鍵のローテーション戦略、本番デプロイ)は TLS 証明書ピンニング をご覧ください。
関連ページ
| タイプ | 詳細リファレンス |
|---|---|
Result / RequestInfo / ResponseInfo / RequestMeta | Result |
SessionManager メソッド | セッション管理 |
DomainClient 実装 | ドメインクライアント |
DownloadConfig / DownloadResult | ファイルダウンロード |
ClientError / ErrorType / エラー変数 | エラータイプ |
FormData / FileData / BodyKind | 定数とタイプ |