Skip to content

Commit cf23b28

Browse files
committed
Make sure we escape all URL params to avoid encoding issues
1 parent c069a7d commit cf23b28

3 files changed

Lines changed: 13 additions & 10 deletions

File tree

internal/stt/assemblyai.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"io"
77
"net/http"
8+
"net/url"
89
"os"
910
"strings"
1011
"time"
@@ -145,7 +146,7 @@ func (a *AssemblyAISTT) upload(data []byte) (string, error) {
145146
}
146147

147148
func (a *AssemblyAISTT) poll(transcriptID string, timestamps bool) (*provider.TranscriptionResult, error) {
148-
url := fmt.Sprintf("%s/transcript/%s", assemblyAIEndpoint, transcriptID)
149+
url := fmt.Sprintf("%s/transcript/%s", assemblyAIEndpoint, url.PathEscape(transcriptID))
149150

150151
for {
151152
if config.Debug() {

internal/tts/elevenlabs.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"io"
77
"net/http"
8+
"net/url"
89
"strings"
910

1011
"github.com/Cloverhound/prompt-tools-cli/internal/audio"
@@ -69,13 +70,13 @@ func (e *ElevenLabsTTS) Synthesize(req *provider.TTSRequest) (*provider.TTSResul
6970
return nil, err
7071
}
7172

72-
url := fmt.Sprintf("%s/text-to-speech/%s?output_format=%s", elevenlabsEndpoint, voiceID, outputFormat)
73+
reqURL := fmt.Sprintf("%s/text-to-speech/%s?output_format=%s", elevenlabsEndpoint, url.PathEscape(voiceID), url.QueryEscape(outputFormat))
7374

7475
if config.Debug() {
75-
fmt.Printf("[DEBUG] POST %s\n", url)
76+
fmt.Printf("[DEBUG] POST %s\n", reqURL)
7677
}
7778

78-
httpReq, err := http.NewRequest("POST", url, strings.NewReader(string(bodyJSON)))
79+
httpReq, err := http.NewRequest("POST", reqURL, strings.NewReader(string(bodyJSON)))
7980
if err != nil {
8081
return nil, err
8182
}

internal/tts/google.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"io"
88
"net/http"
9+
"net/url"
910
"strings"
1011
"unicode"
1112

@@ -181,7 +182,7 @@ func (g *GoogleTTS) synthesizeCloudTTSGemini(req *provider.TTSRequest) (*provide
181182
// If explicit, uses that. Otherwise queries the API for available TTS models
182183
// and picks the best one (prefers "pro" over "flash").
183184
func (g *GoogleTTS) resolveGeminiModel() (string, error) {
184-
url := fmt.Sprintf("%s/models?key=%s", geminiAPIEndpoint, g.apiKey)
185+
url := fmt.Sprintf("%s/models?key=%s", geminiAPIEndpoint, url.QueryEscape(g.apiKey))
185186
resp, err := http.Get(url)
186187
if err != nil {
187188
return "", fmt.Errorf("listing Gemini models: %w", err)
@@ -279,7 +280,7 @@ func (g *GoogleTTS) synthesizeGemini(req *provider.TTSRequest) (*provider.TTSRes
279280
return nil, err
280281
}
281282

282-
url := fmt.Sprintf("%s/models/%s:generateContent?key=%s", geminiAPIEndpoint, model, g.apiKey)
283+
url := fmt.Sprintf("%s/models/%s:generateContent?key=%s", geminiAPIEndpoint, url.PathEscape(model), url.QueryEscape(g.apiKey))
283284

284285
if config.Debug() {
285286
fmt.Printf("[DEBUG] POST %s/models/%s:generateContent\n", geminiAPIEndpoint, model)
@@ -417,7 +418,7 @@ func (g *GoogleTTS) synthesizeCloudTTS(req *provider.TTSRequest) (*provider.TTSR
417418
httpReq.Header.Set("Content-Type", "application/json")
418419
httpReq.Header.Set("Authorization", "Bearer "+g.bearerToken)
419420
} else {
420-
url := fmt.Sprintf("%s/text:synthesize?key=%s", googleTTSEndpoint, g.apiKey)
421+
url := fmt.Sprintf("%s/text:synthesize?key=%s", googleTTSEndpoint, url.QueryEscape(g.apiKey))
421422
httpReq, err = http.NewRequest("POST", url, strings.NewReader(string(bodyJSON)))
422423
if err != nil {
423424
return nil, err
@@ -467,17 +468,17 @@ func (g *GoogleTTS) ListVoices(languageCode string) ([]provider.Voice, error) {
467468
if g.bearerToken != "" {
468469
reqURL := fmt.Sprintf("%s/voices", googleTTSEndpoint)
469470
if languageCode != "" {
470-
reqURL += "?languageCode=" + languageCode
471+
reqURL += "?languageCode=" + url.QueryEscape(languageCode)
471472
}
472473
httpReq, err = http.NewRequest("GET", reqURL, nil)
473474
if err != nil {
474475
return nil, err
475476
}
476477
httpReq.Header.Set("Authorization", "Bearer "+g.bearerToken)
477478
} else {
478-
reqURL := fmt.Sprintf("%s/voices?key=%s", googleTTSEndpoint, g.apiKey)
479+
reqURL := fmt.Sprintf("%s/voices?key=%s", googleTTSEndpoint, url.QueryEscape(g.apiKey))
479480
if languageCode != "" {
480-
reqURL += "&languageCode=" + languageCode
481+
reqURL += "&languageCode=" + url.QueryEscape(languageCode)
481482
}
482483
httpReq, err = http.NewRequest("GET", reqURL, nil)
483484
if err != nil {

0 commit comments

Comments
 (0)