|
1 | 1 | const http = require('http'); |
| 2 | +const https = require('https'); |
| 3 | +const fs = require('fs'); |
2 | 4 | const cluster = require('cluster'); |
3 | 5 | const formidable = require('formidable'); |
4 | 6 | const os = require('os'); |
@@ -357,88 +359,113 @@ plugins.connectToAllDatabases().then(function() { |
357 | 359 |
|
358 | 360 | plugins.dispatch("/worker", {common: common}); |
359 | 361 |
|
360 | | - http.Server((req, res) => { |
361 | | - const params = { |
362 | | - qstring: {}, |
363 | | - res: res, |
364 | | - req: req |
| 362 | + const serverOptions = { |
| 363 | + port: common.config.api.port, |
| 364 | + host: common.config.api.host || '' |
| 365 | + }; |
| 366 | + |
| 367 | + let server; |
| 368 | + if (common.config.api.ssl && common.config.api.ssl.enabled) { |
| 369 | + const sslOptions = { |
| 370 | + key: fs.readFileSync(common.config.api.ssl.key), |
| 371 | + cert: fs.readFileSync(common.config.api.ssl.cert) |
365 | 372 | }; |
| 373 | + if (common.config.api.ssl.ca) { |
| 374 | + sslOptions.ca = fs.readFileSync(common.config.api.ssl.ca); |
| 375 | + } |
| 376 | + server = https.createServer(sslOptions, handleRequest); |
| 377 | + } |
| 378 | + else { |
| 379 | + server = http.createServer(handleRequest); |
| 380 | + } |
366 | 381 |
|
367 | | - if (req.method.toLowerCase() === 'post') { |
368 | | - const formidableOptions = {}; |
369 | | - if (countlyConfig.api.maxUploadFileSize) { |
370 | | - formidableOptions.maxFileSize = countlyConfig.api.maxUploadFileSize; |
371 | | - } |
| 382 | + server.listen(serverOptions.port, serverOptions.host).timeout = common.config.api.timeout || 120000; |
| 383 | + } |
| 384 | +}); |
372 | 385 |
|
373 | | - const form = new formidable.IncomingForm(formidableOptions); |
374 | | - if (/crash_symbols\/(add_symbol|upload_symbol)/.test(req.url)) { |
375 | | - req.body = []; |
376 | | - req.on('data', (data) => { |
377 | | - req.body.push(data); |
378 | | - }); |
| 386 | +/** |
| 387 | + * Handle incoming HTTP/HTTPS requests |
| 388 | + * @param {http.IncomingMessage} req - The request object |
| 389 | + * @param {http.ServerResponse} res - The response object |
| 390 | + */ |
| 391 | +function handleRequest(req, res) { |
| 392 | + const params = { |
| 393 | + qstring: {}, |
| 394 | + res: res, |
| 395 | + req: req |
| 396 | + }; |
| 397 | + |
| 398 | + if (req.method.toLowerCase() === 'post') { |
| 399 | + const formidableOptions = {}; |
| 400 | + if (countlyConfig.api.maxUploadFileSize) { |
| 401 | + formidableOptions.maxFileSize = countlyConfig.api.maxUploadFileSize; |
| 402 | + } |
| 403 | + |
| 404 | + const form = new formidable.IncomingForm(formidableOptions); |
| 405 | + if (/crash_symbols\/(add_symbol|upload_symbol)/.test(req.url)) { |
| 406 | + req.body = []; |
| 407 | + req.on('data', (data) => { |
| 408 | + req.body.push(data); |
| 409 | + }); |
| 410 | + } |
| 411 | + else { |
| 412 | + req.body = ''; |
| 413 | + req.on('data', (data) => { |
| 414 | + req.body += data; |
| 415 | + }); |
| 416 | + } |
| 417 | + |
| 418 | + let multiFormData = false; |
| 419 | + // Check if we have 'multipart/form-data' |
| 420 | + if (req.headers['content-type']?.startsWith('multipart/form-data')) { |
| 421 | + multiFormData = true; |
| 422 | + } |
| 423 | + |
| 424 | + form.parse(req, (err, fields, files) => { |
| 425 | + //handle bakcwards compatability with formiddble v1 |
| 426 | + for (let i in files) { |
| 427 | + if (files[i].filepath) { |
| 428 | + files[i].path = files[i].filepath; |
379 | 429 | } |
380 | | - else { |
381 | | - req.body = ''; |
382 | | - req.on('data', (data) => { |
383 | | - req.body += data; |
384 | | - }); |
| 430 | + if (files[i].mimetype) { |
| 431 | + files[i].type = files[i].mimetype; |
385 | 432 | } |
386 | | - |
387 | | - let multiFormData = false; |
388 | | - // Check if we have 'multipart/form-data' |
389 | | - if (req.headers['content-type']?.startsWith('multipart/form-data')) { |
390 | | - multiFormData = true; |
| 433 | + if (files[i].originalFilename) { |
| 434 | + files[i].name = files[i].originalFilename; |
391 | 435 | } |
392 | | - |
393 | | - form.parse(req, (err, fields, files) => { |
394 | | - //handle bakcwards compatability with formiddble v1 |
395 | | - for (let i in files) { |
396 | | - if (files[i].filepath) { |
397 | | - files[i].path = files[i].filepath; |
398 | | - } |
399 | | - if (files[i].mimetype) { |
400 | | - files[i].type = files[i].mimetype; |
401 | | - } |
402 | | - if (files[i].originalFilename) { |
403 | | - files[i].name = files[i].originalFilename; |
404 | | - } |
405 | | - } |
406 | | - params.files = files; |
407 | | - if (multiFormData) { |
408 | | - let formDataUrl = []; |
409 | | - for (const i in fields) { |
410 | | - params.qstring[i] = fields[i]; |
411 | | - formDataUrl.push(`${i}=${fields[i]}`); |
412 | | - } |
413 | | - params.formDataUrl = formDataUrl.join('&'); |
414 | | - } |
415 | | - else { |
416 | | - for (const i in fields) { |
417 | | - params.qstring[i] = fields[i]; |
418 | | - } |
419 | | - } |
420 | | - if (!params.apiPath) { |
421 | | - processRequest(params); |
422 | | - } |
423 | | - }); |
424 | | - } |
425 | | - else if (req.method.toLowerCase() === 'options') { |
426 | | - const headers = {}; |
427 | | - headers["Access-Control-Allow-Origin"] = "*"; |
428 | | - headers["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"; |
429 | | - headers["Access-Control-Allow-Headers"] = "countly-token, Content-Type"; |
430 | | - res.writeHead(200, headers); |
431 | | - res.end(); |
432 | 436 | } |
433 | | - //attempt process GET request |
434 | | - else if (req.method.toLowerCase() === 'get') { |
435 | | - processRequest(params); |
| 437 | + params.files = files; |
| 438 | + if (multiFormData) { |
| 439 | + let formDataUrl = []; |
| 440 | + for (const i in fields) { |
| 441 | + params.qstring[i] = fields[i]; |
| 442 | + formDataUrl.push(`${i}=${fields[i]}`); |
| 443 | + } |
| 444 | + params.formDataUrl = formDataUrl.join('&'); |
436 | 445 | } |
437 | 446 | else { |
438 | | - common.returnMessage(params, 405, "Method not allowed"); |
| 447 | + for (const i in fields) { |
| 448 | + params.qstring[i] = fields[i]; |
| 449 | + } |
439 | 450 | } |
440 | | - }).listen(common.config.api.port, common.config.api.host || '').timeout = common.config.api.timeout || 120000; |
441 | | - |
442 | | - plugins.loadConfigs(common.db); |
| 451 | + if (!params.apiPath) { |
| 452 | + processRequest(params); |
| 453 | + } |
| 454 | + }); |
443 | 455 | } |
444 | | -}); |
| 456 | + else if (req.method.toLowerCase() === 'options') { |
| 457 | + const headers = {}; |
| 458 | + headers["Access-Control-Allow-Origin"] = "*"; |
| 459 | + headers["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"; |
| 460 | + headers["Access-Control-Allow-Headers"] = "countly-token, Content-Type"; |
| 461 | + res.writeHead(200, headers); |
| 462 | + res.end(); |
| 463 | + } |
| 464 | + //attempt process GET request |
| 465 | + else if (req.method.toLowerCase() === 'get') { |
| 466 | + processRequest(params); |
| 467 | + } |
| 468 | + else { |
| 469 | + common.returnMessage(params, 405, "Method not allowed"); |
| 470 | + } |
| 471 | +} |
0 commit comments