44import cluster from 'cluster' ;
55import { createFrameworkLogger } from '../logger/index.js' ;
66import { ObjectPoolManager } from '../pooling/object-pool-manager.js' ;
7- import {
8- HttpRequest ,
9- HttpResponse ,
10- HttpHandler ,
11- Middleware ,
12- RouteEntry ,
13- } from '../../types/http.js' ;
7+ import { HttpRequest , HttpResponse , Middleware } from '../../types/http.js' ;
148
159/**
1610 * uWebSockets HTTP Server Adapter
@@ -50,6 +44,23 @@ export class UWebSocketsHttpServer {
5044 serverError : Buffer . from ( '{"success":false,"error":"Internal server error"}' ) ,
5145 } ;
5246
47+ // Pre-cached status strings for common codes (performance optimization)
48+ private static readonly STATUS_STRINGS = new Map ( [
49+ [ 200 , '200 OK' ] ,
50+ [ 201 , '201 Created' ] ,
51+ [ 204 , '204 No Content' ] ,
52+ [ 301 , '301 Moved Permanently' ] ,
53+ [ 302 , '302 Found' ] ,
54+ [ 304 , '304 Not Modified' ] ,
55+ [ 400 , '400 Bad Request' ] ,
56+ [ 401 , '401 Unauthorized' ] ,
57+ [ 403 , '403 Forbidden' ] ,
58+ [ 404 , '404 Not Found' ] ,
59+ [ 500 , '500 Internal Server Error' ] ,
60+ [ 502 , '502 Bad Gateway' ] ,
61+ [ 503 , '503 Service Unavailable' ] ,
62+ ] ) ;
63+
5364 constructor (
5465 options : {
5566 ssl ?: { key_file_name ?: string ; cert_file_name ?: string ; passphrase ?: string } ;
@@ -161,7 +172,7 @@ export class UWebSocketsHttpServer {
161172 res . writeHeader ( 'Content-Type' , 'application/json' ) ;
162173 res . end ( '{"success":false,"error":"Internal server error"}' ) ;
163174 } ) ;
164- } catch ( writeError ) {
175+ } catch {
165176 this . logger . error ( 'Failed to send error response' , 'ResponseError' ) ;
166177 }
167178 }
@@ -182,7 +193,7 @@ export class UWebSocketsHttpServer {
182193 }
183194 }
184195
185- private createMoroRequest ( req : any , res : any ) : HttpRequest {
196+ private createMoroRequest ( req : any , _res : any ) : HttpRequest {
186197 const url = req . getUrl ( ) ;
187198 const queryString = req . getQuery ( ) ;
188199 const methodRaw = req . getMethod ( ) ;
@@ -235,10 +246,54 @@ export class UWebSocketsHttpServer {
235246 return httpReq ;
236247 }
237248
249+ // Optimized helper to write headers - avoids Object.entries() overhead
250+ private static writeHeaders (
251+ res : any ,
252+ headers : Record < string , string | string [ ] > ,
253+ headerKeys : string [ ]
254+ ) : void {
255+ const len = headerKeys . length ;
256+ // Fast-path for common cases
257+ if ( len === 0 ) return ;
258+
259+ if ( len === 1 ) {
260+ // Single header (most common case) - no loop needed
261+ const key = headerKeys [ 0 ] ;
262+ const value = headers [ key ] ;
263+ res . writeHeader ( key , Array . isArray ( value ) ? value . join ( ', ' ) : String ( value ) ) ;
264+ return ;
265+ }
266+
267+ if ( len === 2 ) {
268+ // Two headers - unroll loop
269+ const key0 = headerKeys [ 0 ] ;
270+ const value0 = headers [ key0 ] ;
271+ res . writeHeader ( key0 , Array . isArray ( value0 ) ? value0 . join ( ', ' ) : String ( value0 ) ) ;
272+
273+ const key1 = headerKeys [ 1 ] ;
274+ const value1 = headers [ key1 ] ;
275+ res . writeHeader ( key1 , Array . isArray ( value1 ) ? value1 . join ( ', ' ) : String ( value1 ) ) ;
276+ return ;
277+ }
278+
279+ // Multiple headers - use loop
280+ for ( let i = 0 ; i < len ; i ++ ) {
281+ const key = headerKeys [ i ] ;
282+ const value = headers [ key ] ;
283+ res . writeHeader ( key , Array . isArray ( value ) ? value . join ( ', ' ) : String ( value ) ) ;
284+ }
285+ }
286+
287+ // Helper to get status string (cached for performance)
288+ private static getStatusString ( code : number ) : string {
289+ return UWebSocketsHttpServer . STATUS_STRINGS . get ( code ) || `${ code } OK` ;
290+ }
291+
238292 private createMoroResponse ( req : any , res : any ) : HttpResponse {
239293 let headersSent = false ;
240294 let statusCode = 200 ;
241295 const responseHeaders : Record < string , string | string [ ] > = { } ;
296+ let headerKeys : string [ ] = [ ] ; // Track header keys for fast iteration
242297 //eslint-disable-next-line @typescript-eslint/no-this-alias
243298 const self = this ;
244299
@@ -255,7 +310,11 @@ export class UWebSocketsHttpServer {
255310 } ,
256311
257312 setHeader ( name : string , value : string | string [ ] ) {
258- responseHeaders [ name . toLowerCase ( ) ] = value ;
313+ const lowerName = name . toLowerCase ( ) ;
314+ if ( ! ( lowerName in responseHeaders ) ) {
315+ headerKeys . push ( lowerName ) ;
316+ }
317+ responseHeaders [ lowerName ] = value ;
259318 return httpRes as HttpResponse ;
260319 } ,
261320
@@ -264,26 +323,33 @@ export class UWebSocketsHttpServer {
264323 } ,
265324
266325 removeHeader ( name : string ) {
267- delete responseHeaders [ name . toLowerCase ( ) ] ;
326+ const lowerName = name . toLowerCase ( ) ;
327+ if ( lowerName in responseHeaders ) {
328+ delete responseHeaders [ lowerName ] ;
329+ headerKeys = headerKeys . filter ( k => k !== lowerName ) ;
330+ }
268331 return httpRes as HttpResponse ;
269332 } ,
270333
271334 async json ( data : any ) {
272335 if ( headersSent || res . aborted ) return ;
273336
274337 const body = JSON . stringify ( data ) ;
275- responseHeaders [ 'content-type' ] = 'application/json' ;
338+
339+ // Set content-type if not already set
340+ if ( ! ( 'content-type' in responseHeaders ) ) {
341+ responseHeaders [ 'content-type' ] = 'application/json' ;
342+ headerKeys . push ( 'content-type' ) ;
343+ }
276344
277345 try {
278346 res . cork ( ( ) => {
279- res . writeStatus ( `${ statusCode } OK` ) ;
280- Object . entries ( responseHeaders ) . forEach ( ( [ key , value ] ) => {
281- res . writeHeader ( key , Array . isArray ( value ) ? value . join ( ', ' ) : String ( value ) ) ;
282- } ) ;
347+ res . writeStatus ( UWebSocketsHttpServer . getStatusString ( statusCode ) ) ;
348+ UWebSocketsHttpServer . writeHeaders ( res , responseHeaders , headerKeys ) ;
283349 res . end ( body ) ;
284350 } ) ;
285351 headersSent = true ;
286- } catch ( error ) {
352+ } catch {
287353 self . logger . error ( 'Failed to send JSON response' , 'ResponseError' ) ;
288354 }
289355 } ,
@@ -295,14 +361,12 @@ export class UWebSocketsHttpServer {
295361
296362 try {
297363 res . cork ( ( ) => {
298- res . writeStatus ( `${ statusCode } OK` ) ;
299- Object . entries ( responseHeaders ) . forEach ( ( [ key , value ] ) => {
300- res . writeHeader ( key , Array . isArray ( value ) ? value . join ( ', ' ) : String ( value ) ) ;
301- } ) ;
364+ res . writeStatus ( UWebSocketsHttpServer . getStatusString ( statusCode ) ) ;
365+ UWebSocketsHttpServer . writeHeaders ( res , responseHeaders , headerKeys ) ;
302366 res . end ( body ) ;
303367 } ) ;
304368 headersSent = true ;
305- } catch ( error ) {
369+ } catch {
306370 self . logger . error ( 'Failed to send response' , 'ResponseError' ) ;
307371 }
308372 } ,
@@ -315,15 +379,13 @@ export class UWebSocketsHttpServer {
315379
316380 try {
317381 res . cork ( ( ) => {
318- res . writeStatus ( `${ statusCode } OK` ) ;
319- Object . entries ( responseHeaders ) . forEach ( ( [ key , value ] ) => {
320- res . writeHeader ( key , Array . isArray ( value ) ? value . join ( ', ' ) : String ( value ) ) ;
321- } ) ;
382+ res . writeStatus ( UWebSocketsHttpServer . getStatusString ( statusCode ) ) ;
383+ UWebSocketsHttpServer . writeHeaders ( res , responseHeaders , headerKeys ) ;
322384 res . end ( data || '' ) ;
323385 } ) ;
324386 headersSent = true ;
325387 if ( typeof callback === 'function' ) callback ( ) ;
326- } catch ( error ) {
388+ } catch {
327389 self . logger . error ( 'Failed to end response' , 'ResponseError' ) ;
328390 if ( typeof callback === 'function' ) callback ( ) ;
329391 }
@@ -339,32 +401,34 @@ export class UWebSocketsHttpServer {
339401
340402 try {
341403 res . cork ( ( ) => {
342- res . writeStatus ( ` ${ redirectCode } Found` ) ;
404+ res . writeStatus ( UWebSocketsHttpServer . getStatusString ( redirectCode ) ) ;
343405 res . writeHeader ( 'Location' , url ) ;
406+ // Write any existing headers
407+ UWebSocketsHttpServer . writeHeaders ( res , responseHeaders , headerKeys ) ;
344408 res . end ( ) ;
345409 } ) ;
346410 headersSent = true ;
347- } catch ( error ) {
411+ } catch {
348412 self . logger . error ( 'Failed to send redirect' , 'ResponseError' ) ;
349413 }
350414 } ,
351415
352416 // EventEmitter compatibility - stub implementations for middleware
353- on ( event : string , callback : Function ) {
417+ on ( _event : string , _callback : ( ... args : any [ ] ) => void ) {
354418 // uWebSockets doesn't use events like Node.js, but middleware might try to listen
355419 // Only implement 'finish' and 'close' events as stubs
356420 return httpRes ;
357421 } ,
358422
359- once ( event : string , callback : Function ) {
423+ once ( _event : string , _callback : ( ... args : any [ ] ) => void ) {
360424 return httpRes ;
361425 } ,
362426
363- emit ( event : string , ...args : any [ ] ) {
427+ emit ( _event : string , ..._args : any [ ] ) {
364428 return true ;
365429 } ,
366430
367- removeListener ( event : string , callback : Function ) {
431+ removeListener ( _event : string , _callback : ( ... args : any [ ] ) => void ) {
368432 return httpRes ;
369433 } ,
370434
@@ -380,15 +444,17 @@ export class UWebSocketsHttpServer {
380444 if ( options . sameSite ) cookie += `; SameSite=${ options . sameSite } ` ;
381445 }
382446
383- const existing = responseHeaders [ 'set-cookie' ] ;
447+ const lowerKey = 'set-cookie' ;
448+ const existing = responseHeaders [ lowerKey ] ;
384449 if ( existing ) {
385450 if ( Array . isArray ( existing ) ) {
386- responseHeaders [ 'set-cookie' ] = [ ...existing , cookie ] ;
451+ responseHeaders [ lowerKey ] = [ ...existing , cookie ] ;
387452 } else {
388- responseHeaders [ 'set-cookie' ] = [ existing as string , cookie ] ;
453+ responseHeaders [ lowerKey ] = [ existing as string , cookie ] ;
389454 }
390455 } else {
391- responseHeaders [ 'set-cookie' ] = cookie ;
456+ responseHeaders [ lowerKey ] = cookie ;
457+ headerKeys . push ( lowerKey ) ;
392458 }
393459
394460 return httpRes as HttpResponse ;
@@ -399,7 +465,7 @@ export class UWebSocketsHttpServer {
399465 }
400466
401467 private async readBody ( res : any , httpReq : HttpRequest ) : Promise < void > {
402- return new Promise ( ( resolve , reject ) => {
468+ return new Promise ( resolve => {
403469 let buffer : Buffer ;
404470
405471 res . onData ( ( chunk : ArrayBuffer , isLast : boolean ) => {
@@ -429,7 +495,7 @@ export class UWebSocketsHttpServer {
429495 }
430496
431497 resolve ( ) ;
432- } catch ( error ) {
498+ } catch {
433499 this . logger . error ( 'Failed to parse request body' , 'BodyParseError' ) ;
434500 httpReq . body = null ;
435501 resolve ( ) ;
@@ -494,7 +560,7 @@ export class UWebSocketsHttpServer {
494560 this . hookManager = hookManager ;
495561 }
496562
497- configurePerformance ( config : any ) : void {
563+ configurePerformance ( _config : any ) : void {
498564 // uWebSockets is already highly optimized
499565 // This method exists for API compatibility
500566 this . logger . debug ( 'Performance configuration noted (uWebSockets is pre-optimized)' , 'Config' ) ;
@@ -519,7 +585,6 @@ export class UWebSocketsHttpServer {
519585
520586 // Check if we're in a cluster environment
521587 const isClusterWorker = cluster . isWorker ;
522- const isClusterPrimary = cluster . isPrimary ;
523588
524589 // ALWAYS use LIBUS_LISTEN_EXCLUSIVE_PORT when clustering
525590 // This enables SO_REUSEPORT at the OS level, allowing multiple processes to bind to the same port
@@ -569,7 +634,7 @@ export class UWebSocketsHttpServer {
569634 this . logger . info ( 'uWebSockets HTTP server closed' , 'Close' ) ;
570635 }
571636 if ( callback ) callback ( ) ;
572- } catch ( error ) {
637+ } catch {
573638 this . logger . error ( 'Error closing server' , 'Close' ) ;
574639 if ( callback ) callback ( ) ;
575640 }
0 commit comments