Test-XiaoshuLegacySyncBridge.ps1 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. [CmdletBinding()]
  2. param(
  3. [Parameter(Mandatory = $true)]
  4. [string]$BaseUrl,
  5. [Parameter(Mandatory = $true)]
  6. [string]$ConfigurationPath
  7. )
  8. $ErrorActionPreference = 'Stop'
  9. Set-StrictMode -Version Latest
  10. if (-not (Test-Path -LiteralPath $ConfigurationPath -PathType Leaf)) { throw "配置文件不存在:$ConfigurationPath" }
  11. $configuration = Get-Content -LiteralPath $ConfigurationPath -Raw | ConvertFrom-Json
  12. $keyId = [string]$configuration.XiaoshuSync.KeyId
  13. $secret = [string]$configuration.XiaoshuSync.Secret
  14. if ([string]::IsNullOrWhiteSpace($keyId) -or $secret.Length -lt 32) { throw '配置文件中的 KeyId 或 Secret 无效。' }
  15. $base = $BaseUrl.TrimEnd('/')
  16. $health = Invoke-RestMethod -Uri "$base/v1/health" -Method Get -TimeoutSec 15
  17. if ($health.status -ne 'ok') { throw '健康检查返回异常。' }
  18. $baseUri = [Uri]$base
  19. $pathBase = $baseUri.AbsolutePath.TrimEnd('/')
  20. $pathAndQuery = "$pathBase/v1/manifest"
  21. $timestamp = [DateTimeOffset]::UtcNow.ToUnixTimeSeconds().ToString()
  22. $nonce = [Guid]::NewGuid().ToString('N')
  23. $emptyBodyHash = [Convert]::ToHexString([Security.Cryptography.SHA256]::HashData([Text.Encoding]::UTF8.GetBytes(''))).ToLowerInvariant()
  24. $canonical = "GET`n$pathAndQuery`n$timestamp`n$nonce`n$emptyBodyHash"
  25. $hmac = [Security.Cryptography.HMACSHA256]::new([Text.Encoding]::UTF8.GetBytes($secret))
  26. try {
  27. $signature = [Convert]::ToHexString($hmac.ComputeHash([Text.Encoding]::UTF8.GetBytes($canonical))).ToLowerInvariant()
  28. } finally {
  29. $hmac.Dispose()
  30. }
  31. $headers = @{
  32. 'X-Xiaoshu-Key-Id' = $keyId
  33. 'X-Xiaoshu-Timestamp' = $timestamp
  34. 'X-Xiaoshu-Nonce' = $nonce
  35. 'X-Xiaoshu-Signature' = $signature
  36. }
  37. $manifest = Invoke-RestMethod -Uri "$base/v1/manifest" -Method Get -Headers $headers -TimeoutSec 120
  38. if (-not $manifest.manifestTime -or @($manifest.datasets).Count -lt 10 -or $manifest.consistent -ne $true) { throw 'manifest 返回结构不完整或读取期间旧库仍在变化,请稍后重试。' }
  39. Write-Host "健康检查:通过($($health.time))"
  40. Write-Host "数据水位:$($manifest.manifestTime)"
  41. @($manifest.datasets) | Select-Object key, label, count, watermark | Format-Table -AutoSize