11import EventEmitter from "node:events" ;
22import http from "node:http" ;
33import packageJson from "../package.json" with { type : "json" } ;
4+ import { Authenticator } from "./auth/Authenticator.js" ;
45import { Request } from "./Request.js" ;
56import { EmptyResponse } from "./response/index.js" ;
67import { Response } from "./response/Response.js" ;
@@ -12,19 +13,24 @@ import {ServerErrorRegistry} from "./ServerErrorRegistry.js";
1213 * An HTTP server.
1314 * @see {@link Server.Events } for events.
1415 */
15- class Server extends EventEmitter < Server . Events > {
16+ class Server < A > extends EventEmitter < Server . Events > {
1617 /**
1718 * Headers sent with every response.
1819 */
1920 public readonly globalHeaders : Headers ;
21+
2022 /**
2123 * This server's route registry.
2224 */
23- public readonly routes = new RouteRegistry ( ) ;
25+ public readonly routes = new RouteRegistry < A > ( ) ;
26+
27+ /** @internal */
28+ public readonly _authenticators : Authenticator < A > [ ] ;
29+
2430 /**
2531 * This server's error registry.
2632 */
27- public readonly errors = new ServerErrorRegistry ( ) ;
33+ public readonly errors = new ServerErrorRegistry < A > ( ) ;
2834 private readonly server : http . Server ;
2935 private readonly port ?: number ;
3036 private readonly copyOrigin : boolean ;
@@ -34,19 +40,20 @@ class Server extends EventEmitter<Server.Events> {
3440 * Create a new HTTP server.
3541 * @param options Server options.
3642 */
37- public constructor ( options ?: Server . Options ) {
43+ public constructor ( options ?: Server . Options < A > ) {
3844 super ( ) ;
3945 this . server = http . createServer ( {
4046 joinDuplicateHeaders : true ,
4147 } , this . listener . bind ( this ) ) ;
4248
4349 this . globalHeaders = new Headers ( options ?. globalHeaders ) ;
4450 if ( ! this . globalHeaders . has ( "server" ) )
45- this . globalHeaders . set ( "Server" , `cldn /${ packageJson . version } ` ) ;
51+ this . globalHeaders . set ( "Server" , `${ packageJson . name } /${ packageJson . version } ` ) ;
4652
4753 this . port = options ?. port ;
4854 this . copyOrigin = options ?. copyOrigin ?? false ;
4955 this . handleConditionalRequests = options ?. handleConditionalRequests ?? true ;
56+ this . _authenticators = options ?. authenticators ?? [ ] ;
5057
5158 if ( this . port !== undefined ) this . listen ( this . port ) . then ( ) ;
5259
@@ -101,21 +108,21 @@ class Server extends EventEmitter<Server.Events> {
101108 }
102109
103110 private async listener ( req : http . IncomingMessage , res : http . ServerResponse ) {
104- let apiRequest : Request ;
111+ let apiRequest : Request < A > ;
105112 try {
106- apiRequest = Request . incomingMessage ( req ) ;
113+ apiRequest = Request . incomingMessage ( req , this ) ;
107114 }
108115 catch ( e ) {
109116 if ( e instanceof Request . BadUrlError ) {
110- this . errors . _get ( ServerErrorRegistry . ErrorCodes . BAD_URL , null ) . _send ( res , this ) ;
117+ await this . errors . _get ( ServerErrorRegistry . ErrorCodes . BAD_URL , null ) . _send ( res ) ;
111118 return ;
112119 }
113120
114121 if ( e instanceof Request . SocketClosedError )
115122 return ;
116123
117124 this . emit ( "error" , e as any ) ;
118- this . errors . _get ( ServerErrorRegistry . ErrorCodes . INTERNAL , null ) . _send ( res , this ) ;
125+ await this . errors . _get ( ServerErrorRegistry . ErrorCodes . INTERNAL , null ) . _send ( res ) ;
119126 return ;
120127 }
121128
@@ -127,7 +134,7 @@ class Server extends EventEmitter<Server.Events> {
127134 apiRequest . _responseHeaders . set ( "vary" , "origin" ) ;
128135 }
129136
130- let response : Response ;
137+ let response : Response < A > ;
131138 try {
132139 response = await this . routes . handle ( apiRequest ) ;
133140 }
@@ -148,13 +155,13 @@ class Server extends EventEmitter<Server.Events> {
148155 await this . sendResponse ( response , res , apiRequest ) ;
149156 }
150157
151- private async sendResponse ( response : Response , res : http . ServerResponse , req : Request ) : Promise < void > {
158+ private async sendResponse ( response : Response < A > , res : http . ServerResponse , req : Request < A > ) : Promise < void > {
152159 conditional: if (
153160 this . handleConditionalRequests
154161 && response . statusCode === 200
155162 && [ Request . Method . GET , Request . Method . HEAD ] . includes ( req . method )
156163 ) {
157- const responseHeaders = response . allHeaders ( res , this , req ) ;
164+ const responseHeaders = response . allHeaders ( res , req ) ;
158165 const etag = responseHeaders . get ( "etag" ) ;
159166 const lastModified = responseHeaders . has ( "last-modified" )
160167 ? new Date ( responseHeaders . get ( "last-modified" ) ! )
@@ -166,26 +173,26 @@ class Server extends EventEmitter<Server.Events> {
166173 if ( ! this . getETags ( req . headers . get ( "if-match" ) ! )
167174 . filter ( t => ! t . startsWith ( "W/" ) )
168175 . includes ( etag ! ) )
169- return this . errors . _get ( ServerErrorRegistry . ErrorCodes . PRECONDITION_FAILED , req ) . _send ( res , this , req ) ;
176+ return this . errors . _get ( ServerErrorRegistry . ErrorCodes . PRECONDITION_FAILED , req ) . _send ( res , req ) ;
170177 }
171178 else if ( req . headers . has ( "if-unmodified-since" ) ) {
172179 if ( lastModified === null
173180 || lastModified . getTime ( ) > new Date ( req . headers . get ( "if-unmodified-since" ) ! ) . getTime ( ) )
174- return this . errors . _get ( ServerErrorRegistry . ErrorCodes . PRECONDITION_FAILED , req ) . _send ( res , this , req ) ;
181+ return this . errors . _get ( ServerErrorRegistry . ErrorCodes . PRECONDITION_FAILED , req ) . _send ( res , req ) ;
175182 }
176183
177184 if ( req . headers . has ( "if-none-match" ) ) {
178185 if ( this . getETags ( req . headers . get ( "if-none-match" ) ! )
179186 . includes ( etag ! ) )
180- return new EmptyResponse ( responseHeaders , 304 ) . _send ( res , this , req ) ;
187+ return new EmptyResponse < A > ( responseHeaders , 304 ) . _send ( res , req ) ;
181188 }
182189 else if ( req . headers . has ( "if-modified-since" ) ) {
183190 if ( lastModified !== null
184191 && lastModified . getTime ( ) <= new Date ( req . headers . get ( "if-modified-since" ) ! ) . getTime ( ) )
185- return new EmptyResponse ( responseHeaders , 304 ) . _send ( res , this , req ) ;
192+ return new EmptyResponse < A > ( responseHeaders , 304 ) . _send ( res , req ) ;
186193 }
187194 }
188- response . _send ( res , this , req ) ;
195+ await response . _send ( res , req ) ;
189196 }
190197
191198 private getETags ( header : string ) {
@@ -199,7 +206,7 @@ namespace Server {
199206 /**
200207 * Server options
201208 */
202- export interface Options {
209+ export interface Options < A > {
203210 /**
204211 * The HTTP listener port. From 1 to 65535. Ports 1–1023 require
205212 * privileges. If not set, {@link Server#listen|Server.listen()} must be called manually.
@@ -225,6 +232,11 @@ namespace Server {
225232 * @default true
226233 */
227234 readonly handleConditionalRequests ?: boolean ;
235+
236+ /**
237+ * Authenticators for handling request authentication.
238+ */
239+ readonly authenticators ?: Authenticator < A > [ ] ;
228240 }
229241
230242 /**
0 commit comments