package yuyuecha import ( "sort" "strings" ) // 签名头固定顺序,便于阅读与对比 var preferredHeaderOrder = []string{ "Content-Type", "clientId", "timestamp", "nonce", "signature", } // generateCurlCommand 生成可复现的 curl 命令,便于数据源排查 func generateCurlCommand(method, url string, headers map[string]string, body string) string { var cmd strings.Builder cmd.WriteString("curl -X ") cmd.WriteString(method) cmd.WriteString(" '") cmd.WriteString(url) cmd.WriteString("'") for _, key := range orderedHeaderKeys(headers) { cmd.WriteString(" \\\n -H '") cmd.WriteString(escapeShellSingleQuote(key)) cmd.WriteString(": ") cmd.WriteString(escapeShellSingleQuote(headers[key])) cmd.WriteString("'") } if body != "" { cmd.WriteString(" \\\n -d '") cmd.WriteString(escapeShellSingleQuote(body)) cmd.WriteString("'") } return cmd.String() } func orderedHeaderKeys(headers map[string]string) []string { seen := make(map[string]struct{}, len(headers)) keys := make([]string, 0, len(headers)) for _, key := range preferredHeaderOrder { if _, ok := headers[key]; ok { keys = append(keys, key) seen[key] = struct{}{} } } rest := make([]string, 0, len(headers)) for key := range headers { if _, ok := seen[key]; !ok { rest = append(rest, key) } } sort.Strings(rest) return append(keys, rest...) } func escapeShellSingleQuote(s string) string { return strings.ReplaceAll(s, "'", `'\''`) }