Skip to content

Commit

Permalink
Solution
Browse files Browse the repository at this point in the history
  • Loading branch information
Basil-Panasiuk committed Apr 26, 2024
1 parent c46de53 commit 1888316
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 2 deletions.
25 changes: 25 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Compression app</title>
</head>
<body>
<form method="POST" action="/compress" enctype="multipart/form-data">
<label>
Select a file
<input type="file" name="file" />
</label>
<label>
Compression type:
<select name="compressionType">
<option value="gzip" default>gzip</option>
<option value="deflate">deflate</option>
<option value="br">br</option>
</select>
</label>
<button>Submit</button>
</form>
</body>
</html>
95 changes: 93 additions & 2 deletions src/createServer.js
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down

0 comments on commit 1888316

Please sign in to comment.