@@ -11,8 +11,6 @@ const dbg = require('../util/debug_module')(__filename);
1111if ( ! dbg . get_process_name ( ) ) dbg . set_process_name ( 'Endpoint' ) ;
1212
1313const util = require ( 'util' ) ;
14- const http = require ( 'http' ) ;
15- const https = require ( 'https' ) ;
1614const os = require ( 'os' ) ;
1715
1816const P = require ( '../util/promise' ) ;
@@ -28,7 +26,7 @@ const StsSDK = require('../sdk/sts_sdk');
2826const ObjectIO = require ( '../sdk/object_io' ) ;
2927const ObjectSDK = require ( '../sdk/object_sdk' ) ;
3028const xml_utils = require ( '../util/xml_utils' ) ;
31- const ssl_utils = require ( '../util/ssl_utils ' ) ;
29+ const http_utils = require ( '../util/http_utils ' ) ;
3230const net_utils = require ( '../util/net_utils' ) ;
3331const addr_utils = require ( '../util/addr_utils' ) ;
3432const fork_utils = require ( '../util/fork_utils' ) ;
@@ -57,7 +55,8 @@ if (process.env.NOOBAA_LOG_LEVEL) {
5755const SERVICES_TYPES_ENUM = Object . freeze ( {
5856 S3 : 'S3' ,
5957 STS : 'STS' ,
60- IAM : 'IAM'
58+ IAM : 'IAM' ,
59+ METRICS : 'METRICS'
6160} ) ;
6261
6362const new_umask = process . env . NOOBAA_ENDPOINT_UMASK || 0o000 ;
@@ -66,7 +65,7 @@ let fork_count;
6665dbg . log0 ( 'endpoint: replacing old umask: ' , old_umask . toString ( 8 ) , 'with new umask: ' , new_umask . toString ( 8 ) ) ;
6766
6867/**
69- * @typedef {http.IncomingMessage & {
68+ * @typedef {import(' http') .IncomingMessage & {
7069 * object_sdk?: ObjectSDK;
7170 * func_sdk?: FuncSDK;
7271 * sts_sdk?: StsSDK;
@@ -79,7 +78,7 @@ dbg.log0('endpoint: replacing old umask: ', old_umask.toString(8), 'with new uma
7978/**
8079 * @typedef {(
8180 * req: EndpointRequest,
82- * res: http.ServerResponse
81+ * res: import(' http') .ServerResponse
8382 * ) => void | Promise<void>} EndpointHandler
8483 */
8584
@@ -89,18 +88,14 @@ dbg.log0('endpoint: replacing old umask: ', old_umask.toString(8), 'with new uma
8988 * https_port?: number;
9089 * https_port_sts?: number;
9190 * https_port_iam?: number;
92- * metrics_port?: number;
91+ * http_metrics_port?: number;
92+ * https_metrics_port?: number;
9393 * nsfs_config_root?: string;
9494 * init_request_sdk?: EndpointHandler;
9595 * forks?: number;
9696 * }} EndpointOptions
9797 */
9898
99- // An internal function to prevent code duplication
100- async function create_https_server ( ssl_cert_info , honorCipherOrder , endpoint_handler ) {
101- const ssl_options = { ...ssl_cert_info . cert , honorCipherOrder : honorCipherOrder } ;
102- return https . createServer ( ssl_options , endpoint_handler ) ;
103- }
10499
105100/**
106101 * @param {EndpointOptions } options
@@ -117,7 +112,8 @@ async function main(options = {}) {
117112
118113 // the primary just forks and returns, workers will continue to serve
119114 fork_count = options . forks ?? config . ENDPOINT_FORKS ;
120- const metrics_port = options . metrics_port || config . EP_METRICS_SERVER_PORT ;
115+ const http_metrics_port = options . http_metrics_port || config . EP_METRICS_SERVER_PORT ;
116+ const https_metrics_port = options . https_metrics_port || config . EP_METRICS_SERVER_SSL_PORT ;
121117 /**
122118 * Please notice that we can run the main in 2 states:
123119 * 1. Only the primary process runs the main (fork is 0 or undefined) - everything that
@@ -127,7 +123,8 @@ async function main(options = {}) {
127123 * fork_utils.start_workers because the primary process returns after start_workers
128124 * and the forks will continue executing the code lines in this function
129125 * */
130- const is_workers_started_from_primary = await fork_utils . start_workers ( metrics_port , fork_count ) ;
126+ const is_workers_started_from_primary = await fork_utils . start_workers ( http_metrics_port , https_metrics_port ,
127+ options . nsfs_config_root , fork_count ) ;
131128 if ( is_workers_started_from_primary ) return ;
132129
133130 const endpoint_group_id = process . env . ENDPOINT_GROUP_ID || 'default-endpoint-group' ;
@@ -200,17 +197,15 @@ async function main(options = {}) {
200197 const https_port_sts = options . https_port_sts || config . ENDPOINT_SSL_STS_PORT ;
201198 const https_port_iam = options . https_port_iam || config . ENDPOINT_SSL_IAM_PORT ;
202199
203- await start_server_and_cert ( SERVICES_TYPES_ENUM . S3 , init_request_sdk ,
200+ await start_endpoint_server_and_cert ( SERVICES_TYPES_ENUM . S3 , init_request_sdk ,
204201 { ...options , https_port : https_port_s3 , http_port : http_port_s3 , virtual_hosts, bucket_logger, notification_logger } ) ;
205- await start_server_and_cert ( SERVICES_TYPES_ENUM . STS , init_request_sdk , { https_port : https_port_sts , virtual_hosts } ) ;
206- await start_server_and_cert ( SERVICES_TYPES_ENUM . IAM , init_request_sdk , { https_port : https_port_iam } ) ;
202+ await start_endpoint_server_and_cert ( SERVICES_TYPES_ENUM . STS , init_request_sdk , { https_port : https_port_sts , virtual_hosts } ) ;
203+ await start_endpoint_server_and_cert ( SERVICES_TYPES_ENUM . IAM , init_request_sdk , { https_port : https_port_iam } ) ;
207204
208205
209206 // START METRICS SERVER
210- if ( metrics_port > 0 && cluster . isPrimary ) {
211- dbg . log0 ( 'Starting metrics server' , metrics_port ) ;
212- await prom_reporting . start_server ( metrics_port , false ) ;
213- dbg . log0 ( 'Started metrics server successfully' ) ;
207+ if ( ( http_metrics_port > 0 || https_metrics_port > 0 ) && cluster . isPrimary ) {
208+ await prom_reporting . start_server ( http_metrics_port , https_metrics_port , false , options . nsfs_config_root ) ;
214209 }
215210
216211 // TODO: currently NC NSFS deployments don't have internal_rpc_client nor db,
@@ -249,40 +244,26 @@ async function main(options = {}) {
249244}
250245
251246/**
252- * start_server_and_cert starts the server by type and options and creates a certificate if required
247+ * start_endpoint_server_and_cert starts the server by type and options and creates a certificate if required
253248 * @param {('S3'|'IAM'|'STS') } server_type
254249 * @param {EndpointHandler } init_request_sdk
255250 * @param {{ http_port?: number, https_port?: number, virtual_hosts?: readonly string[],
256251 * bucket_logger?: PersistentLogger, notification_logger?: PersistentLogger,
257252 * nsfs_config_root?: string}} options
258253 */
259- async function start_server_and_cert ( server_type , init_request_sdk , options = { } ) {
254+ async function start_endpoint_server_and_cert ( server_type , init_request_sdk , options = { } ) {
260255 const { http_port, https_port, nsfs_config_root } = options ;
261256 const endpoint_request_handler = create_endpoint_handler ( server_type , init_request_sdk , options ) ;
262257
263258 if ( server_type === SERVICES_TYPES_ENUM . S3 ) {
264259 if ( nsfs_config_root && ! config . ALLOW_HTTP ) {
265260 dbg . warn ( 'HTTP is not allowed for NC NSFS.' ) ;
266261 } else {
267- const http_server = http . createServer ( endpoint_request_handler ) ;
268- if ( http_port > 0 ) {
269- dbg . log0 ( `Starting ${ server_type } HTTP - ${ http_port } ` ) ;
270- await listen_http ( http_port , http_server ) ;
271- dbg . log0 ( `Started ${ server_type } HTTP successfully` ) ;
272- }
262+ await http_utils . start_http_server ( http_port , server_type , endpoint_request_handler ) ;
273263 }
274264 }
275265 if ( https_port > 0 ) {
276- const ssl_cert_info = await ssl_utils . get_ssl_cert_info ( server_type , nsfs_config_root ) ;
277- const https_server = await create_https_server ( ssl_cert_info , true , endpoint_request_handler ) ;
278- ssl_cert_info . on ( 'update' , updated_ssl_cert_info => {
279- dbg . log0 ( `Setting updated ${ server_type } ssl certs for endpoint.` ) ;
280- const updated_ssl_options = { ...updated_ssl_cert_info . cert , honorCipherOrder : true } ;
281- https_server . setSecureContext ( updated_ssl_options ) ;
282- } ) ;
283- dbg . log0 ( `Starting ${ server_type } HTTPS - ${ https_port } ` ) ;
284- await listen_http ( https_port , https_server ) ;
285- dbg . log0 ( `Started ${ server_type } HTTPS successfully` ) ;
266+ await http_utils . start_https_server ( https_port , server_type , endpoint_request_handler , nsfs_config_root ) ;
286267 }
287268}
288269
@@ -506,68 +487,6 @@ function unavailable_handler(req, res) {
506487 res . end ( reply ) ;
507488}
508489
509- function listen_http ( port , server ) {
510- return new Promise ( ( resolve , reject ) => {
511- setup_http_server ( server ) ;
512- server . listen ( port , err => {
513- if ( err ) {
514- dbg . error ( 'ENDPOINT FAILED to listen' , err ) ;
515- reject ( err ) ;
516- } else {
517- resolve ( ) ;
518- }
519- } ) ;
520- } ) ;
521- }
522-
523- function setup_http_server ( server ) {
524- // Handle 'Expect' header different than 100-continue to conform with AWS.
525- // Consider any expect value as if the client is expecting 100-continue.
526- // See https://github.com/ceph/s3-tests/blob/master/s3tests/functional/test_headers.py:
527- // - test_object_create_bad_expect_mismatch()
528- // - test_object_create_bad_expect_empty()
529- // - test_object_create_bad_expect_none()
530- // - test_object_create_bad_expect_unreadable()
531- // See https://nodejs.org/api/http.html#http_event_checkexpectation
532- server . on ( 'checkExpectation' , function on_s3_check_expectation ( req , res ) {
533- res . writeContinue ( ) ;
534- server . emit ( 'request' , req , res ) ;
535- } ) ;
536-
537- // See https://nodejs.org/api/http.html#http_event_clienterror
538- server . on ( 'clientError' , function on_s3_client_error ( err , socket ) {
539-
540- // On parsing errors we reply 400 Bad Request to conform with AWS
541- // These errors come from the nodejs native http parser.
542- if ( typeof err . code === 'string' &&
543- err . code . startsWith ( 'HPE_INVALID_' ) &&
544- err . bytesParsed > 0 ) {
545- console . error ( 'ENDPOINT CLIENT ERROR - REPLY WITH BAD REQUEST' , err ) ;
546- socket . write ( 'HTTP/1.1 400 Bad Request\r\n' ) ;
547- socket . write ( `Date: ${ new Date ( ) . toUTCString ( ) } \r\n` ) ;
548- socket . write ( 'Connection: close\r\n' ) ;
549- socket . write ( 'Content-Length: 0\r\n' ) ;
550- socket . end ( '\r\n' ) ;
551- }
552-
553- // in any case we destroy the socket
554- socket . destroy ( ) ;
555- } ) ;
556-
557- server . keepAliveTimeout = config . ENDPOINT_HTTP_SERVER_KEEPALIVE_TIMEOUT ;
558- server . requestTimeout = config . ENDPOINT_HTTP_SERVER_REQUEST_TIMEOUT ;
559- server . maxRequestsPerSocket = config . ENDPOINT_HTTP_MAX_REQUESTS_PER_SOCKET ;
560-
561- server . on ( 'error' , handle_server_error ) ;
562-
563- // This was an attempt to read from the socket in large chunks,
564- // but it seems like it has no effect and we still get small chunks
565- // server.on('connection', function on_s3_connection(socket) {
566- // socket._readableState.highWaterMark = 1024 * 1024;
567- // socket.setNoDelay(true);
568- // });
569- }
570-
571490exports . main = main ;
572491exports . create_endpoint_handler = create_endpoint_handler ;
573492exports . create_init_request_sdk = create_init_request_sdk ;
0 commit comments