1+ const API_URL = 'https://maas-coding-api.cn-huabei-1.xf-yun.com/v2/chat/completions'
2+ const REQUEST_TIMEOUT = 55000
3+
4+ async function pipeStream ( response , res ) {
5+ res . status ( 200 )
6+ res . setHeader ( 'Content-Type' , 'text/event-stream; charset=utf-8' )
7+ res . setHeader ( 'Cache-Control' , 'no-cache, no-transform' )
8+ res . setHeader ( 'Connection' , 'keep-alive' )
9+ res . flushHeaders ?. ( )
10+
11+ const reader = response . body . getReader ( )
12+
13+ while ( true ) {
14+ const { value, done } = await reader . read ( )
15+
16+ if ( done ) {
17+ break
18+ }
19+
20+ res . write ( Buffer . from ( value ) )
21+ }
22+
23+ res . end ( )
24+ }
25+
126module . exports = async function handler ( req , res ) {
227 const ALLOWED_ORIGINS = new Set ( [
328 'https://iflytek.github.io' ,
@@ -8,42 +33,66 @@ module.exports = async function handler(req, res) {
833
934 const requestOrigin = req . headers . origin ;
1035
11- // Allow localhost, the main site, and any vercel preview deployments
1236 if ( requestOrigin && ( ALLOWED_ORIGINS . has ( requestOrigin ) || requestOrigin . endsWith ( '.vercel.app' ) ) ) {
13- res . setHeader ( 'Access-Control-Allow-Origin' , requestOrigin ) ;
14- res . setHeader ( 'Vary' , 'Origin' ) ;
37+ res . setHeader ( 'Access-Control-Allow-Origin' , requestOrigin )
38+ res . setHeader ( 'Vary' , 'Origin' )
1539 }
1640
17- res . setHeader ( 'Access-Control-Allow-Methods' , 'GET,POST,OPTIONS' ) ;
18- res . setHeader ( 'Access-Control-Allow-Headers' , 'Content-Type,Authorization' ) ;
41+ res . setHeader ( 'Access-Control-Allow-Methods' , 'GET,POST,OPTIONS' )
42+ res . setHeader ( 'Access-Control-Allow-Headers' , 'Content-Type,Authorization' )
1943
2044 if ( req . method === 'OPTIONS' ) {
21- return res . status ( 204 ) . end ( ) ;
45+ return res . status ( 204 ) . end ( )
2246 }
2347
2448 if ( req . method !== 'POST' ) {
25- return res . status ( 405 ) . json ( { error : 'Method Not Allowed' } ) ;
49+ return res . status ( 405 ) . json ( { error : 'Method Not Allowed' } )
2650 }
2751
52+ const controller = new AbortController ( )
53+ const timeoutId = setTimeout ( ( ) => controller . abort ( ) , REQUEST_TIMEOUT )
54+ const requestBody = req . body && typeof req . body === 'object' ? req . body : { }
55+
2856 try {
29- const response = await fetch ( 'https://maas-coding-api.cn-huabei-1.xf-yun.com/v2/chat/completions' , {
57+ const response = await fetch ( API_URL , {
3058 method : 'POST' ,
3159 headers : {
3260 'Content-Type' : 'application/json' ,
3361 'Authorization' : `Bearer ${ process . env . VITE_API_KEY } `
3462 } ,
35- body : JSON . stringify ( { ...req . body , stream : false } )
36- } ) ;
63+ body : JSON . stringify ( requestBody ) ,
64+ signal : controller . signal
65+ } )
3766
3867 if ( ! response . ok ) {
39- const errorText = await response . text ( ) ;
40- return res . status ( response . status ) . send ( `API Error: ${ response . status } ${ errorText } ` ) ;
68+ const errorText = await response . text ( )
69+ return res . status ( response . status ) . send ( `API Error: ${ response . status } ${ errorText } ` )
4170 }
4271
43- const data = await response . json ( ) ;
44- return res . status ( 200 ) . json ( data ) ;
72+ if ( requestBody . stream && response . body ) {
73+ await pipeStream ( response , res )
74+ return
75+ }
76+
77+ const data = await response . json ( )
78+ return res . status ( 200 ) . json ( data )
4579 } catch ( error ) {
46- console . error ( 'Proxy Error:' , error ) ;
47- return res . status ( 500 ) . json ( { error : 'Internal Server Error' , details : error . message } ) ;
80+ console . error ( 'Proxy Error:' , error )
81+
82+ if ( res . headersSent ) {
83+ if ( ! res . writableEnded ) {
84+ res . write ( `data: ${ JSON . stringify ( { error : error . message } ) } \n\n` )
85+ res . end ( )
86+ }
87+ return
88+ }
89+
90+ if ( controller . signal . aborted ) {
91+ return res . status ( 504 ) . json ( { error : 'Gateway Timeout' , details : 'Upstream request timed out' } )
92+ }
93+
94+ return res . status ( 500 ) . json ( { error : 'Internal Server Error' , details : error . message } )
95+ } finally {
96+ clearTimeout ( timeoutId )
4897 }
4998}
0 commit comments