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