From 1888316d2c7b482d7bcc5816a0186738c0ba7fbe Mon Sep 17 00:00:00 2001 From: Basil-Panasiuk Date: Fri, 26 Apr 2024 21:39:42 +0300 Subject: [PATCH] Solution --- public/index.html | 25 ++++++++++++ src/createServer.js | 95 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 public/index.html diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..3463046 --- /dev/null +++ b/public/index.html @@ -0,0 +1,25 @@ + + + + + + Compression app + + +
+ + + +
+ + diff --git a/src/createServer.js b/src/createServer.js index 1cf1dda..2bc57bf 100644 --- a/src/createServer.js +++ b/src/createServer.js @@ -1,8 +1,99 @@ 'use strict'; +const http = require('http'); +const fs = require('fs'); +const formidable = require('formidable'); +const zlib = require('zlib'); +const { pipeline } = require('stream'); + +const availableCompressions = ['br', 'gzip', 'deflate']; + +const initCompression = (type) => { + switch (type) { + case 'br': + return zlib.createBrotliCompress(); + case 'deflate': + return zlib.createDeflate(); + default: + return zlib.createGzip(); + } +}; + function createServer() { - /* Write your code here */ - // Return instance of http.Server class + const server = new http.Server(); + + server.on('request', async (req, res) => { + const url = new URL(req.url, `http:${req.headers.host}`); + + res.setHeader('Content-type', 'text/plain'); + + if (url.pathname === '/') { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/html'); + + return fs.createReadStream('public/index.html').pipe(res); + } + + if (url.pathname !== '/compress') { + res.statusCode = 404; + + return res.end('Not found'); + } + + if (req.method !== 'POST') { + res.statusCode = 400; + + return res.end('Invalid request method'); + } + + const form = new formidable.IncomingForm(); + + try { + const [fields, files] = await form.parse(req); + const [targetType] = fields?.compressionType; + const [targetFile] = files?.file; + + if (!targetType || !targetFile) { + res.statusCode = 400; + + return res.end('Invalid form'); + } + + if (!availableCompressions.includes(targetType)) { + res.statusCode = 400; + + return res.end('Invalid compression'); + } + + const fileStream = fs.createReadStream(targetFile.filepath); + const compression = initCompression(targetType); + + res.statusCode = 200; + + res.setHeader( + 'Content-Disposition', + `attachment; filename=${targetFile.originalFilename}.${targetType}`, + ); + + pipeline(fileStream, compression, res, (err) => { + res.statusCode = 500; + + return res.end(String(err)); + }); + + res.on('close', () => { + fileStream.destroy(); + }); + } catch (err) { + res.statusCode = err.httpCode || 400; + + return res.end(String(err)); + } + }); + + server.on('error', () => {}); + + return server; } module.exports = {