@@ -190,16 +190,16 @@ function buildUpstreamPath(reqUrl, targetHost, basePath) {
190190}
191191
192192/**
193- * Strip the ` key` query parameter from a Gemini request URL.
193+ * Strip all known Gemini API- key query parameters from a request URL.
194194 *
195- * The @google/genai SDK (and older Gemini SDK versions) may append `?key=<value>`
196- * to every request URL in addition to setting the `x-goog-api-key` header.
197- * The proxy injects the real key via the header, so the placeholder `key=`
198- * value must be removed before forwarding to Google to prevent
199- * API_KEY_INVALID errors.
195+ * The @google/genai SDK (and older Gemini SDK versions) may append auth params
196+ * (`?key=`, `?apiKey=`, or `?api_key=`) to every request URL in addition to
197+ * setting the `x-goog-api-key` header. The proxy injects the real key via the
198+ * header, so any placeholder param must be removed before forwarding to Google
199+ * to prevent API_KEY_INVALID errors.
200200 *
201201 * @param {string } reqUrl - The incoming request URL (must start with exactly one '/')
202- * @returns {string } URL with the `key` query parameter removed
202+ * @returns {string } URL with all Gemini auth query parameters removed
203203 */
204204function stripGeminiKeyParam ( reqUrl ) {
205205 // Only operate on relative request paths that begin with exactly one slash.
@@ -211,6 +211,8 @@ function stripGeminiKeyParam(reqUrl) {
211211 }
212212 const parsed = new URL ( reqUrl , 'http://localhost' ) ;
213213 parsed . searchParams . delete ( 'key' ) ;
214+ parsed . searchParams . delete ( 'apiKey' ) ;
215+ parsed . searchParams . delete ( 'api_key' ) ;
214216 // Reconstruct relative path only — never emit the scheme/host from the dummy base.
215217 return parsed . pathname + parsed . search ;
216218}
@@ -1355,7 +1357,7 @@ if (require.main === module) {
13551357 const contentLength = parseInt ( req . headers [ 'content-length' ] , 10 ) || 0 ;
13561358 if ( checkRateLimit ( req , res , 'gemini' , contentLength ) ) return ;
13571359
1358- // Strip any ?key= query parameter — the @google/genai SDK may append it to the URL .
1360+ // Strip any auth query params ( ?key=, ?apiKey=, ?api_key=) — the SDK may append them .
13591361 // The proxy injects the real key via x-goog-api-key header instead.
13601362 req . url = stripGeminiKeyParam ( req . url ) ;
13611363
@@ -1365,13 +1367,14 @@ if (require.main === module) {
13651367 } ) ;
13661368
13671369 geminiServer . on ( 'upgrade' , ( req , socket , head ) => {
1368- // Strip any ?key= query parameter — the @google/genai SDK may append it to the URL .
1370+ // Strip any auth query params ( ?key=, ?apiKey=, ?api_key=) — the SDK may append them .
13691371 req . url = stripGeminiKeyParam ( req . url ) ;
13701372 proxyWebSocket ( req , socket , head , GEMINI_API_TARGET , {
13711373 'x-goog-api-key' : GEMINI_API_KEY ,
13721374 } , 'gemini' , GEMINI_API_BASE_PATH ) ;
13731375 } ) ;
13741376
1377+ logRequest ( 'info' , 'server_start' , { message : `GEMINI_API_KEY configured (length=${ GEMINI_API_KEY . length } )` } ) ;
13751378 geminiServer . listen ( 10003 , '0.0.0.0' , ( ) => {
13761379 logRequest ( 'info' , 'server_start' , { message : 'Google Gemini proxy listening on port 10003' , target : GEMINI_API_TARGET } ) ;
13771380 onListenerReady ( ) ;
@@ -1395,6 +1398,7 @@ if (require.main === module) {
13951398 socket . destroy ( ) ;
13961399 } ) ;
13971400
1401+ logRequest ( 'warn' , 'server_start' , { message : 'GEMINI_API_KEY not set — Gemini proxy will return 503' } ) ;
13981402 geminiServer . listen ( 10003 , '0.0.0.0' , ( ) => {
13991403 logRequest ( 'info' , 'server_start' , { message : 'Gemini endpoint listening on port 10003 (Gemini not configured — returning 503)' } ) ;
14001404 } ) ;
0 commit comments