perbaikan response
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"api-service/internal/config"
|
||||
"api-service/internal/models/vclaim/peserta"
|
||||
@@ -18,16 +19,6 @@ import (
|
||||
)
|
||||
|
||||
// cleanResponse removes invalid characters and BOM from the response string
|
||||
func cleanResponse(resp string) string {
|
||||
// Remove UTF-8 BOM
|
||||
resp = strings.TrimPrefix(resp, "\xef\xbb\xbf")
|
||||
resp = strings.TrimPrefix(resp, "\ufeff")
|
||||
// Remove null characters
|
||||
resp = strings.ReplaceAll(resp, "\x00", "")
|
||||
// Trim whitespace
|
||||
resp = strings.TrimSpace(resp)
|
||||
return resp
|
||||
}
|
||||
|
||||
// VClaimService interface for VClaim operations
|
||||
type VClaimService interface {
|
||||
@@ -201,6 +192,17 @@ func (s *Service) processResponse(res *http.Response) (*ResponDTOVclaim, error)
|
||||
Int("key_length", len(decryptionKey)).
|
||||
Msg("Decryption key components")
|
||||
|
||||
// // Decrypt response
|
||||
// consID, secretKey, userKey, tstamp, _ := s.config.SetHeader()
|
||||
// decryptionKey := GenerateBPJSKey(consID, tstamp, secretKey) // Menggunakan fungsi baru
|
||||
// log.Debug().
|
||||
// Str("consID", consID).
|
||||
// Str("tstamp", tstamp).
|
||||
// Str("userKey", userKey).
|
||||
// Str("secretKey", secretKey).
|
||||
// Int("key_length", len(decryptionKey)).
|
||||
// Msg("Decryption key components")
|
||||
|
||||
respDecrypt, err := ResponseVclaim(respMentah.Response, decryptionKey)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to decrypt response")
|
||||
@@ -211,9 +213,28 @@ func (s *Service) processResponse(res *http.Response) (*ResponDTOVclaim, error)
|
||||
if respDecrypt != "" {
|
||||
// Clean the decrypted response
|
||||
respDecrypt = cleanResponse(respDecrypt)
|
||||
if err := json.Unmarshal([]byte(respDecrypt), &finalResp.Response); err != nil {
|
||||
// If JSON unmarshal fails, store as string
|
||||
log.Warn().Err(err).Msg("Failed to unmarshal decrypted response, storing as string")
|
||||
|
||||
// Try multiple cleaning strategies
|
||||
cleaningStrategies := []string{
|
||||
respDecrypt,
|
||||
strings.TrimLeft(respDecrypt, "\ufeff\xfe\xef\xbb\xbf"),
|
||||
strings.TrimLeftFunc(respDecrypt, func(r rune) bool { return r < 32 && r != '\n' && r != '\r' && r != '\t' }),
|
||||
}
|
||||
|
||||
var jsonParseSuccess bool
|
||||
for i, cleaned := range cleaningStrategies {
|
||||
if err := json.Unmarshal([]byte(cleaned), &finalResp.Response); err == nil {
|
||||
log.Info().
|
||||
Int("strategy", i+1).
|
||||
Msg("Successfully parsed JSON with cleaning strategy")
|
||||
jsonParseSuccess = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !jsonParseSuccess {
|
||||
// If all JSON parsing fails, store as string
|
||||
log.Warn().Msg("All JSON parsing strategies failed, storing as string")
|
||||
finalResp.Response = respDecrypt
|
||||
}
|
||||
}
|
||||
@@ -477,3 +498,80 @@ func PostRequest(endpoint string, cfg interface{}, data interface{}) interface{}
|
||||
|
||||
return resp
|
||||
}
|
||||
func cleanResponse(s string) string {
|
||||
// Remove UTF-8 BOM dan variasi BOM lainnya
|
||||
s = strings.TrimPrefix(s, "\xef\xbb\xbf") // UTF-8 BOM
|
||||
s = strings.TrimPrefix(s, "\ufeff") // Unicode BOM
|
||||
s = strings.TrimPrefix(s, "\ufffe") // Unicode BOM (reverse)
|
||||
s = strings.TrimPrefix(s, "\xff\xfe") // UTF-16 LE BOM
|
||||
s = strings.TrimPrefix(s, "\xfe\xff") // UTF-16 BE BOM
|
||||
|
||||
// Remove karakter control dan non-printable
|
||||
var result strings.Builder
|
||||
for _, r := range s {
|
||||
if r >= 32 && r <= 126 || r == '\n' || r == '\r' || r == '\t' {
|
||||
result.WriteRune(r)
|
||||
} else if r > 126 && unicode.IsPrint(r) {
|
||||
// Allow Unicode printable characters
|
||||
result.WriteRune(r)
|
||||
}
|
||||
// Skip semua karakter lainnya (termasuk BOM fragments)
|
||||
}
|
||||
|
||||
cleaned := result.String()
|
||||
cleaned = strings.TrimSpace(cleaned)
|
||||
|
||||
// Cari dan ekstrak JSON yang valid
|
||||
if idx := strings.Index(cleaned, "{"); idx >= 0 {
|
||||
cleaned = cleaned[idx:]
|
||||
// Find matching closing brace
|
||||
if endIdx := findMatchingBrace(cleaned); endIdx > 0 {
|
||||
cleaned = cleaned[:endIdx+1]
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("cleanResponse: Final cleaned length: %d", len(cleaned))
|
||||
log.Printf("cleanResponse: Final result preview: %s", cleaned[:min(200, len(cleaned))])
|
||||
return cleaned
|
||||
}
|
||||
|
||||
// Fungsi helper untuk menemukan closing brace yang matching
|
||||
func findMatchingBrace(s string) int {
|
||||
if len(s) == 0 || s[0] != '{' {
|
||||
return -1
|
||||
}
|
||||
|
||||
braceCount := 0
|
||||
inString := false
|
||||
escaped := false
|
||||
|
||||
for i, char := range s {
|
||||
if escaped {
|
||||
escaped = false
|
||||
continue
|
||||
}
|
||||
|
||||
if char == '\\' {
|
||||
escaped = true
|
||||
continue
|
||||
}
|
||||
|
||||
if char == '"' && !escaped {
|
||||
inString = !inString
|
||||
continue
|
||||
}
|
||||
|
||||
if !inString {
|
||||
if char == '{' {
|
||||
braceCount++
|
||||
} else if char == '}' {
|
||||
braceCount--
|
||||
if braceCount == 0 {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user