|
6 | 6 | "fmt" |
7 | 7 | "io" |
8 | 8 | "net/http" |
| 9 | + "net/url" |
9 | 10 | "strings" |
10 | 11 | "unicode" |
11 | 12 |
|
@@ -181,7 +182,7 @@ func (g *GoogleTTS) synthesizeCloudTTSGemini(req *provider.TTSRequest) (*provide |
181 | 182 | // If explicit, uses that. Otherwise queries the API for available TTS models |
182 | 183 | // and picks the best one (prefers "pro" over "flash"). |
183 | 184 | 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)) |
185 | 186 | resp, err := http.Get(url) |
186 | 187 | if err != nil { |
187 | 188 | return "", fmt.Errorf("listing Gemini models: %w", err) |
@@ -279,7 +280,7 @@ func (g *GoogleTTS) synthesizeGemini(req *provider.TTSRequest) (*provider.TTSRes |
279 | 280 | return nil, err |
280 | 281 | } |
281 | 282 |
|
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)) |
283 | 284 |
|
284 | 285 | if config.Debug() { |
285 | 286 | fmt.Printf("[DEBUG] POST %s/models/%s:generateContent\n", geminiAPIEndpoint, model) |
@@ -417,7 +418,7 @@ func (g *GoogleTTS) synthesizeCloudTTS(req *provider.TTSRequest) (*provider.TTSR |
417 | 418 | httpReq.Header.Set("Content-Type", "application/json") |
418 | 419 | httpReq.Header.Set("Authorization", "Bearer "+g.bearerToken) |
419 | 420 | } 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)) |
421 | 422 | httpReq, err = http.NewRequest("POST", url, strings.NewReader(string(bodyJSON))) |
422 | 423 | if err != nil { |
423 | 424 | return nil, err |
@@ -467,17 +468,17 @@ func (g *GoogleTTS) ListVoices(languageCode string) ([]provider.Voice, error) { |
467 | 468 | if g.bearerToken != "" { |
468 | 469 | reqURL := fmt.Sprintf("%s/voices", googleTTSEndpoint) |
469 | 470 | if languageCode != "" { |
470 | | - reqURL += "?languageCode=" + languageCode |
| 471 | + reqURL += "?languageCode=" + url.QueryEscape(languageCode) |
471 | 472 | } |
472 | 473 | httpReq, err = http.NewRequest("GET", reqURL, nil) |
473 | 474 | if err != nil { |
474 | 475 | return nil, err |
475 | 476 | } |
476 | 477 | httpReq.Header.Set("Authorization", "Bearer "+g.bearerToken) |
477 | 478 | } 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)) |
479 | 480 | if languageCode != "" { |
480 | | - reqURL += "&languageCode=" + languageCode |
| 481 | + reqURL += "&languageCode=" + url.QueryEscape(languageCode) |
481 | 482 | } |
482 | 483 | httpReq, err = http.NewRequest("GET", reqURL, nil) |
483 | 484 | if err != nil { |
|
0 commit comments