@@ -293,6 +293,25 @@ function isJsonStatusError(payload) {
293293 ) ;
294294}
295295
296+ function isHtmlPayload ( payload , headers = { } ) {
297+ const contentType = headers ?. [ 'content-type' ] || headers ?. [ 'Content-Type' ] || '' ;
298+ if ( typeof contentType === 'string' && contentType . toLowerCase ( ) . includes ( 'text/html' ) ) {
299+ return true ;
300+ }
301+ if ( typeof payload !== 'string' ) return false ;
302+ return / < h t m l [ \s > ] / i. test ( payload ) || / < ! d o c t y p e h t m l / i. test ( payload ) ;
303+ }
304+
305+ function normalizeUpstreamError ( status , data , headers = { } ) {
306+ if ( isHtmlPayload ( data , headers ) ) {
307+ return {
308+ status,
309+ data : { error : 'Server not reachable' }
310+ } ;
311+ }
312+ return { status, data } ;
313+ }
314+
296315async function isServerUp ( serverUrl ) {
297316 if ( ! serverUrl || typeof serverUrl !== 'string' ) return false ;
298317
@@ -475,15 +494,19 @@ app.post('/ios-request', trackProxyResponseTime(async (req, res) => {
475494
476495 if ( isJsonStatusError ( cobaltRes . data ) && hasNextTarget ) {
477496 logWithRequestIp ( 'warn' , req , `Server ${ targetUrl } returned JSON status=error, trying next server` ) ;
478- lastServerResponse = { status : cobaltRes . status , data : cobaltRes . data } ;
497+ lastServerResponse = normalizeUpstreamError ( cobaltRes . status , cobaltRes . data , cobaltRes . headers ) ;
479498 continue ;
480499 }
481500
482501 return res . status ( cobaltRes . status ) . json ( cobaltRes . data ) ;
483502 } catch ( err ) {
484503 if ( err . response && isJsonStatusError ( err . response . data ) && hasNextTarget ) {
485504 logWithRequestIp ( 'warn' , req , `Server ${ targetUrl } returned JSON status=error, trying next server` ) ;
486- lastServerResponse = { status : err . response . status , data : err . response . data } ;
505+ lastServerResponse = normalizeUpstreamError (
506+ err . response . status ,
507+ err . response . data ,
508+ err . response . headers
509+ ) ;
487510 continue ;
488511 }
489512 throw err ;
@@ -496,8 +519,13 @@ app.post('/ios-request', trackProxyResponseTime(async (req, res) => {
496519 throw new Error ( 'No server response available.' ) ;
497520 } catch ( err ) {
498521 if ( err . response ) {
499- logWithRequestIp ( 'error' , req , 'Error in /ios-request:' , err . response . data ) ;
500- res . status ( err . response . status ) . json ( err . response . data ) ;
522+ const normalizedError = normalizeUpstreamError (
523+ err . response . status ,
524+ err . response . data ,
525+ err . response . headers
526+ ) ;
527+ logWithRequestIp ( 'error' , req , 'Error in /ios-request:' , normalizedError . data ) ;
528+ res . status ( normalizedError . status ) . json ( normalizedError . data ) ;
501529 } else {
502530 logWithRequestIp ( 'error' , req , 'Error in /ios-request:' , err . message ) ;
503531 res . status ( 500 ) . json ( { error : 'Internal server error' } ) ;
0 commit comments