Use HTTPS for documented Bailian signed audio URLs
This commit is contained in:
@@ -74,10 +74,11 @@ func synthesizeBailianTTS(ctx context.Context, approved TTSConfig, text string)
|
||||
if err := json.Unmarshal(raw, &result); err != nil || result.Output.Audio.URL == "" {
|
||||
return nil, errors.New("Bailian TTS response has no complete audio reference")
|
||||
}
|
||||
if err := bailianURL(result.Output.Audio.URL, true); err != nil {
|
||||
audioURL, err := bailianAudioDownloadURL(result.Output.Audio.URL)
|
||||
if err != nil {
|
||||
return nil, errors.New("Bailian TTS audio reference is invalid")
|
||||
}
|
||||
audioRequest, err := http.NewRequestWithContext(ctx, http.MethodGet, result.Output.Audio.URL, nil)
|
||||
audioRequest, err := http.NewRequestWithContext(ctx, http.MethodGet, audioURL, nil)
|
||||
if err != nil {
|
||||
return nil, errors.New("create Bailian audio request")
|
||||
}
|
||||
@@ -159,6 +160,22 @@ func (w *boundedPCM) Write(data []byte) (int, error) {
|
||||
return w.Buffer.Write(data)
|
||||
}
|
||||
|
||||
// Bailian documents HTTP signed OSS links. Preserve the path and signature
|
||||
// byte-for-byte, but fetch only over HTTPS; never fall back to HTTP.
|
||||
func bailianAudioDownloadURL(raw string) (string, error) {
|
||||
parsed, err := url.Parse(raw)
|
||||
if err != nil {
|
||||
return "", errors.New("invalid audio address")
|
||||
}
|
||||
if strings.HasPrefix(raw, "http://") && parsed.Host == "dashscope-result-bj.oss-cn-beijing.aliyuncs.com" && parsed.User == nil && parsed.Fragment == "" {
|
||||
raw = "https" + raw[len("http"):]
|
||||
}
|
||||
if err := bailianURL(raw, true); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
func bailianURL(raw string, signedAudio bool) error {
|
||||
parsed, err := url.Parse(raw)
|
||||
if err != nil || parsed.Host == "" || parsed.User != nil || parsed.Fragment != "" {
|
||||
|
||||
@@ -51,6 +51,32 @@ func mockBailianTTS(t *testing.T, pcm []byte, observe func(string)) (string, *at
|
||||
return server.URL + "/api/v1/services/aigc/multimodal-generation/generation", calls
|
||||
}
|
||||
|
||||
func TestBailianAudioDownloadURLUpgradesDocumentedOSSHostOnly(t *testing.T) {
|
||||
const from = "http://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/ab%2Fcd.wav?Expires=123&Signature=fake%2Bvalue"
|
||||
const want = "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/ab%2Fcd.wav?Expires=123&Signature=fake%2Bvalue"
|
||||
got, err := bailianAudioDownloadURL(from)
|
||||
if err != nil || got != want {
|
||||
t.Fatalf("audio address = %q, %v; want exact HTTPS upgrade", got, err)
|
||||
}
|
||||
for _, address := range []string{
|
||||
"http://other.oss-cn-beijing.aliyuncs.com/audio.wav?Signature=fake",
|
||||
"http://dashscope-result-bj.oss-cn-beijing.aliyuncs.com:80/audio.wav?Signature=fake",
|
||||
"http://user@dashscope-result-bj.oss-cn-beijing.aliyuncs.com/audio.wav?Signature=fake",
|
||||
"http://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/audio.wav#fragment",
|
||||
} {
|
||||
if _, err := bailianAudioDownloadURL(address); err == nil {
|
||||
t.Fatalf("unapproved HTTP audio address accepted")
|
||||
}
|
||||
}
|
||||
const alreadyHTTPS = "https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/audio.wav?Signature=fake"
|
||||
if got, err := bailianAudioDownloadURL(alreadyHTTPS); err != nil || got != alreadyHTTPS {
|
||||
t.Fatalf("existing HTTPS address changed: %v", err)
|
||||
}
|
||||
if got, err := bailianAudioDownloadURL("http://127.0.0.1/audio.wav"); err != nil || got != "http://127.0.0.1/audio.wav" {
|
||||
t.Fatalf("isolated local Mock address changed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBailianFailureSummaryNeverLogsProviderPayload(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
message, kind string
|
||||
|
||||
Reference in New Issue
Block a user