httputil

package
v1.27.0 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package httputil은 공용 HTTP client, JSON request, response 검증 helper를 제공합니다.

패키지 개요

이 패키지는 서비스 간 HTTP 호출과 외부 API 호출에서 반복되는 client timeout, connection pool, HTTP/2 정책을 TransportProfile로 맞춥니다. 기본 transport의 proxy, keep-alive, TLS 기본값은 유지하고 호출 목적에 맞는 profile만 주입합니다.

JSON request 생성, API key header 적용, response body decode/discard, non-2xx response를 APIError로 변환하는 흐름도 이 패키지에서 제공합니다. 호출부는 error helper로 HTTP status와 API error code를 분기할 수 있습니다.

관리 HTTP surface에서 반복되는 API key 인증, fixed-window rate limiting, trusted proxy client IP 식별도 프레임워크 독립 helper로 제공합니다. gin 전용 adapter는 pkg/httputil/ginauth에 분리되어 있습니다.

주요 사용 패턴

client := httputil.NewExternalAPIClient(30 * time.Second)
resp, err := client.Get(url)
if err != nil {
    return err
}
// non-2xx 시 CheckStatus가 body를 drain+close하므로 아래 defer는 no-op이 됩니다.
// 2xx success 경로에서는 caller가 body를 읽고 닫습니다.
defer resp.Body.Close()
if err := httputil.CheckStatus(resp); err != nil {
    return err
}
if _, err := io.Copy(io.Discard, resp.Body); err != nil {
    return err
}

api := httputil.NewJSONClient(baseURL, apiKey, 10*time.Second)
req, err := api.NewJSONRequest(ctx, http.MethodPost, "/v1/jobs", payload)
if err != nil {
    return err
}
resp, err := api.Do(req)
if err != nil {
    return err
}
// non-2xx 시 CheckStatus가 body를 drain+close하므로 아래 defer는 no-op이 됩니다.
defer resp.Body.Close()
if err := api.CheckStatus(resp); err != nil {
    return err
}
var out jobResponse
if err := api.DecodeJSON(resp, &out); err != nil {
    return err
}

Index

Constants

View Source
const (
	// ContentTypeJSON은 JSON 응답 Content-Type 값이다.
	ContentTypeJSON = "application/json"
	// HeaderAPIKey는 관리 API key 인증 헤더 이름이다.
	HeaderAPIKey = "X-API-Key" //nolint:gosec // 헤더 이름 상수이며 credential 값이 아니다.
)
View Source
const DefaultMaxBodyBytes int64 = 16 << 20

Variables

View Source
var ErrResponseBodyTooLarge = errors.New("httputil: response body exceeds limit")

Functions

func APIKeyFromRequest

func APIKeyFromRequest(r *http.Request) string

APIKeyFromRequest는 X-API-Key 또는 Bearer Authorization 값을 관리 API key로 추출한다.

func AdminAuthMiddleware

func AdminAuthMiddleware(cfg AdminAuthConfig) func(http.Handler) http.Handler

AdminAuthMiddleware는 twentyq형 관리 API key 인증 middleware를 만든다.

func CheckStatus

func CheckStatus(resp *http.Response) error

func ClientIP

func ClientIP(r *http.Request, opts ClientIPOptions) string

ClientIP는 trusted proxy 경계 안에서만 forwarded header를 반영한 client IP를 반환한다.

func ConstantTimeStringEqual

func ConstantTimeStringEqual(left, right string) bool

ConstantTimeStringEqual은 두 문자열을 길이 차이까지 포함해 일정 시간 비교한다.

func DecodeJSON

func DecodeJSON(resp *http.Response, v any) error

func DecodeJSONLimited

func DecodeJSONLimited(resp *http.Response, v any, maxBytes int64) error

func FixedWindowRateLimitMiddleware

func FixedWindowRateLimitMiddleware(cfg RateLimitMiddlewareConfig) func(http.Handler) http.Handler

FixedWindowRateLimitMiddleware는 fixed-window limiter를 net/http middleware로 감싼다.

func IsStatus

func IsStatus(err error, statusCode int) bool

func NewClient

func NewClient(timeout time.Duration) *http.Client

func NewExternalAPIClient

func NewExternalAPIClient(timeout time.Duration) *http.Client

func NewInternalServiceClient

func NewInternalServiceClient(timeout time.Duration) *http.Client

func NewProfiledClient

func NewProfiledClient(profile TransportProfile) *http.Client

기본 keep-alive, proxy, TLS 기본 동작은 유지하고 timeout/pool/HTTP2 정책만 profile로 주입합니다.

func ParseTrustedProxies

func ParseTrustedProxies(values []string) ([]netip.Prefix, error)

ParseTrustedProxies는 IP/CIDR 문자열을 trusted proxy prefix 목록으로 변환한다.

func ParseTrustedProxyCSV

func ParseTrustedProxyCSV(raw string) ([]netip.Prefix, error)

ParseTrustedProxyCSV는 comma-separated trusted proxy CIDR/IP 목록을 변환한다.

func RateLimitIdentity

func RateLimitIdentity(r *http.Request, apiKey string, opts ClientIPOptions) string

RateLimitIdentity는 API key가 있으면 key hash, 아니면 client IP 기반 identity를 반환한다.

func RateLimitKeyHash

func RateLimitKeyHash(value string) string

RateLimitKeyHash는 rate-limit key/log용 짧은 SHA-256 해시를 반환한다.

func WriteErrorJSON

func WriteErrorJSON(w http.ResponseWriter, status int, code, message string) error

WriteErrorJSON은 표준 관리 HTTP JSON 에러 응답을 쓴다.

func WriteRateLimitExceededJSON

func WriteRateLimitExceededJSON(w http.ResponseWriter, _ *http.Request, _ string)

WriteRateLimitExceededJSON은 twentyq형 429 JSON 응답을 쓴다.

Types

type APIError

type APIError struct {
	StatusCode int
	Code       string
	Message    string
	RequestID  string
	Details    map[string]any
	Body       string
	Err        error
}

func (*APIError) Error

func (e *APIError) Error() string

func (*APIError) Unwrap

func (e *APIError) Unwrap() error

type AdminAuthConfig

type AdminAuthConfig struct {
	APIKey   string
	Disabled bool
}

AdminAuthConfig는 관리 API key 인증 middleware 설정이다. Disabled가 false인 zero value는 인증을 강제한다.

type ClientIPOptions

type ClientIPOptions struct {
	TrustForwarded bool
	TrustedProxies []netip.Prefix
	ForwardedMode  ForwardedHeaderMode
}

ClientIPOptions는 forwarded header 신뢰 경계를 지정한다.

type ErrorResponse

type ErrorResponse struct {
	Error   string `json:"error"`
	Message string `json:"message"`
}

ErrorResponse는 관리 HTTP JSON 에러 응답 본문이다.

type FixedWindowOptions

type FixedWindowOptions struct {
	MaxIdentities int
	EntryTTL      time.Duration
	Now           func() time.Time
}

FixedWindowOptions는 fixed-window limiter 선택 동작을 지정한다. MaxIdentities와 EntryTTL의 zero value는 안전 기본값을 사용한다.

type FixedWindowRateLimiter

type FixedWindowRateLimiter struct {
	// contains filtered or unexported fields
}

FixedWindowRateLimiter는 identity별 fixed-window 요청 수를 제한한다.

func NewFixedWindowRateLimiter

func NewFixedWindowRateLimiter(limit int, window time.Duration, opts FixedWindowOptions) *FixedWindowRateLimiter

NewFixedWindowRateLimiter는 fixed-window limiter를 생성한다.

func (*FixedWindowRateLimiter) Allow

func (l *FixedWindowRateLimiter) Allow(identity string) bool

Allow는 identity가 현재 window에서 허용되는지 반환한다.

type ForwardedHeaderMode

type ForwardedHeaderMode int

ForwardedHeaderMode는 trusted proxy에서 전달된 client IP 선택 방식을 지정한다.

const (
	// ForwardedHeaderLeftmost는 X-Forwarded-For의 첫 유효 IP를 선택한다.
	ForwardedHeaderLeftmost ForwardedHeaderMode = iota
	// ForwardedHeaderRightmostNonTrusted는 오른쪽에서 첫 비신뢰 hop을 선택한다.
	ForwardedHeaderRightmostNonTrusted
)

type IdentityFunc

type IdentityFunc func(*http.Request) string

IdentityFunc는 요청에서 rate-limit identity를 만든다.

type JSONClient

type JSONClient struct {
	// contains filtered or unexported fields
}

JSONClient는 내부 서비스 간 JSON API 호출용 공통 HTTP 클라이언트입니다.

func NewJSONClient

func NewJSONClient(baseURL, apiKey string, timeout time.Duration) *JSONClient

NewJSONClient는 공통 internal service client를 생성합니다.

func NewJSONClientWithHTTPClient

func NewJSONClientWithHTTPClient(baseURL, apiKey string, httpClient *http.Client) *JSONClient

NewJSONClientWithHTTPClient는 caller가 준비한 http.Client로 JSONClient를 생성합니다.

func (*JSONClient) CheckStatus

func (c *JSONClient) CheckStatus(resp *http.Response) error

func (*JSONClient) DecodeJSON

func (c *JSONClient) DecodeJSON(resp *http.Response, out any) error

func (*JSONClient) DiscardBody

func (c *JSONClient) DiscardBody(resp *http.Response) error

func (*JSONClient) Do

func (c *JSONClient) Do(req *http.Request) (*http.Response, error)

func (*JSONClient) NewJSONRequest

func (c *JSONClient) NewJSONRequest(ctx context.Context, method, path string, payload any) (*http.Request, error)

NewJSONRequest는 JSON body 요청을 생성합니다.

func (*JSONClient) NewRequest

func (c *JSONClient) NewRequest(ctx context.Context, method, path string) (*http.Request, error)

NewRequest는 body 없는 요청을 생성합니다.

type LoginFailureRateLimiter

type LoginFailureRateLimiter struct {
	// contains filtered or unexported fields
}

LoginFailureRateLimiter는 로그인 실패 횟수 기반 lockout limiter다.

func NewDefaultLoginFailureRateLimiter

func NewDefaultLoginFailureRateLimiter() *LoginFailureRateLimiter

NewDefaultLoginFailureRateLimiter는 admin-dashboard와 같은 기본 lockout 값을 사용한다.

func NewLoginFailureRateLimiter

func NewLoginFailureRateLimiter(opts LoginFailureRateLimiterOptions) *LoginFailureRateLimiter

NewLoginFailureRateLimiter는 로그인 실패 기반 lockout limiter를 생성한다.

func (*LoginFailureRateLimiter) IsAllowed

func (l *LoginFailureRateLimiter) IsAllowed(identity string) (bool, time.Duration)

IsAllowed는 identity가 현재 로그인 시도를 할 수 있는지와 retry-after를 반환한다.

func (*LoginFailureRateLimiter) RecordFailure

func (l *LoginFailureRateLimiter) RecordFailure(identity string) int

RecordFailure는 identity의 실패 횟수를 기록하고 현재 window count를 반환한다.

func (*LoginFailureRateLimiter) RecordSuccess

func (l *LoginFailureRateLimiter) RecordSuccess(identity string)

RecordSuccess는 identity의 실패 기록을 삭제한다.

func (*LoginFailureRateLimiter) Start

func (l *LoginFailureRateLimiter) Start()

Start는 stale attempt cleanup loop를 시작한다.

func (*LoginFailureRateLimiter) Stop

func (l *LoginFailureRateLimiter) Stop()

Stop은 cleanup loop를 정지한다.

type LoginFailureRateLimiterOptions

type LoginFailureRateLimiterOptions struct {
	MaxAttempts     int
	Window          time.Duration
	Lockout         time.Duration
	CleanupInterval time.Duration
	Now             func() time.Time
}

LoginFailureRateLimiterOptions는 로그인 실패 lockout limiter 설정이다.

type RateLimitMiddlewareConfig

type RateLimitMiddlewareConfig struct {
	Limiter  *FixedWindowRateLimiter
	Identity IdentityFunc
	Reject   RateLimitRejectFunc
	Skip     func(*http.Request) bool
}

RateLimitMiddlewareConfig는 fixed-window HTTP middleware 설정이다.

type RateLimitRejectFunc

type RateLimitRejectFunc func(http.ResponseWriter, *http.Request, string)

RateLimitRejectFunc는 rate-limit 초과 응답을 쓴다.

type TransportProfile

type TransportProfile struct {
	Timeout               time.Duration
	DialTimeout           time.Duration
	TLSHandshakeTimeout   time.Duration
	ResponseHeaderTimeout time.Duration
	IdleConnTimeout       time.Duration
	MaxIdleConns          int
	MaxConnsPerHost       int
	MaxIdleConnsPerHost   int
	DisableHTTP2          bool
}

Directories

Path Synopsis
Package ginauth는 gin 기반 관리 API key 인증 middleware를 제공합니다.
Package ginauth는 gin 기반 관리 API key 인증 middleware를 제공합니다.

Jump to

Keyboard shortcuts

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