refactor: apiRetryCount·maxJSONBodySize 상수화, bytes.NewReader 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-13 03:00:34 +09:00
parent e1d0e6fed0
commit bf19d5d542

View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"bytes"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@@ -21,6 +22,9 @@ import (
const ( const (
protocolName = "a301" protocolName = "a301"
gameExeName = "A301.exe" gameExeName = "A301.exe"
apiRetryCount = 3 // fetchServerInfo, redeemTicket 재시도 횟수
maxJSONBodySize = 1 << 20 // JSON 응답 바디 최대 1MB
) )
// serverInfoURL, redeemTicketURL은 빌드 시 -ldflags로 오버라이드 가능. // serverInfoURL, redeemTicketURL은 빌드 시 -ldflags로 오버라이드 가능.
@@ -183,7 +187,7 @@ func retryWithBackoff(maxRetries int, fn func() error) error {
// fetchServerInfo 서버에서 게임/런처 다운로드 정보를 조회한다 (3회 재시도). // fetchServerInfo 서버에서 게임/런처 다운로드 정보를 조회한다 (3회 재시도).
func fetchServerInfo() (*downloadInfo, error) { func fetchServerInfo() (*downloadInfo, error) {
var info *downloadInfo var info *downloadInfo
err := retryWithBackoff(3, func() error { err := retryWithBackoff(apiRetryCount, func() error {
resp, err := apiClient.Get(serverInfoURL) resp, err := apiClient.Get(serverInfoURL)
if err != nil { if err != nil {
return fmt.Errorf("서버 연결 실패: %w", err) return fmt.Errorf("서버 연결 실패: %w", err)
@@ -198,7 +202,7 @@ func fetchServerInfo() (*downloadInfo, error) {
} }
var result downloadInfo var result downloadInfo
if err := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&result); err != nil { if err := json.NewDecoder(io.LimitReader(resp.Body, maxJSONBodySize)).Decode(&result); err != nil {
return fmt.Errorf("서버 응답 파싱 실패: %w", err) return fmt.Errorf("서버 응답 파싱 실패: %w", err)
} }
info = &result info = &result
@@ -213,13 +217,13 @@ func fetchServerInfo() (*downloadInfo, error) {
// redeemTicket 일회용 티켓을 서버에 보내 JWT 액세스 토큰으로 교환한다 (3회 재시도). // redeemTicket 일회용 티켓을 서버에 보내 JWT 액세스 토큰으로 교환한다 (3회 재시도).
func redeemTicket(ticket string) (string, error) { func redeemTicket(ticket string) (string, error) {
var token string var token string
err := retryWithBackoff(3, func() error { err := retryWithBackoff(apiRetryCount, func() error {
payload, err := json.Marshal(map[string]string{"ticket": ticket}) payload, err := json.Marshal(map[string]string{"ticket": ticket})
if err != nil { if err != nil {
return fmt.Errorf("요청 데이터 생성 실패: %w", err) return fmt.Errorf("요청 데이터 생성 실패: %w", err)
} }
resp, err := apiClient.Post(redeemTicketURL, "application/json", strings.NewReader(string(payload))) resp, err := apiClient.Post(redeemTicketURL, "application/json", bytes.NewReader(payload))
if err != nil { if err != nil {
return fmt.Errorf("서버에 연결할 수 없습니다: %w", err) return fmt.Errorf("서버에 연결할 수 없습니다: %w", err)
} }
@@ -235,7 +239,7 @@ func redeemTicket(ticket string) (string, error) {
var result struct { var result struct {
Token string `json:"token"` Token string `json:"token"`
} }
if err := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&result); err != nil { if err := json.NewDecoder(io.LimitReader(resp.Body, maxJSONBodySize)).Decode(&result); err != nil {
return fmt.Errorf("서버 응답을 처리할 수 없습니다: %w", err) return fmt.Errorf("서버 응답을 처리할 수 없습니다: %w", err)
} }
if result.Token == "" { if result.Token == "" {