Skip to content

Commit

Permalink
sol
Browse files Browse the repository at this point in the history
  • Loading branch information
yepolotn1ak committed Jul 8, 2024
1 parent c46de53 commit 93b35d8
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/compressionTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const compressionTypes = ['gzip', 'deflate', 'br'];

module.exports = { compressionTypes };
85 changes: 80 additions & 5 deletions src/createServer.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,85 @@
/* eslint-disable no-console */
'use strict';

const http = require('http');
const fs = require('fs');
const formidable = require('formidable');
const { getCompressedFile } = require('./getCompressedFile');
const { compressionTypes } = require('./compressionTypes');

function createServer() {
/* Write your code here */
// Return instance of http.Server class
const server = new http.Server();

server.on('request', (req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`);
const form = new formidable.IncomingForm();

if (url.pathname !== '/compress') {
res.statusCode = 404;
res.end('Trying to access a non-existing route!');

return;
}

if (url.req.method !== 'POST') {
res.statusCode = 400;
res.end('Use POST request method instead!');

return;
}

if (url.pathname === '/' && req.method === 'GET') {
res.statusCode = 200;
res.end('Ready!');

return;
}

form.parse(req, (err, { compressionType: fields }, { file: files }) => {
if (err || !fields || !files) {
res.statusCode = 400;
res.end('Bad request, form has errors');

return;
}

const [compressionType] = fields;
const [file] = files;

if (!compressionTypes.includes(compressionType)) {
res.statusCode = 404;
res.end('Bad Request: Compression type not supported');

return;
}

res.setHeader(
'Content-Disposition',
`attachment; filename=${file.originalFilename}.${compressionType}`,
);

const fileStream = fs.createReadStream(file.filepath);

fileStream
.on('error', (error) => {
res.statusCode = 500;
res.end('Internal Server Error: Failed to read file', error);
})
.pipe(getCompressedFile(compressionType))
.on('error', (error) => {
res.statusCode = 500;
res.end('Internal Server Error: Failed to compress file', error);
})
.pipe(res)
.on('error', (error) => {
console.error('Error sending response:', error);
});

res.on('error', () => fileStream.destroy());
});
});

return server;
}

module.exports = {
createServer,
};
module.exports = { createServer };
16 changes: 16 additions & 0 deletions src/getCompressedFile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const zlib = require('zlib');

const getCompressedFile = (compressionType) => {
switch (compressionType) {
case 'gzip':
return zlib.createGzip();
case 'deflate':
return zlib.createDeflate();
case 'br':
return zlib.createBrotliCompress();
default:
return null;
}
};

module.exports = { getCompressedFile };
26 changes: 26 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!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 id="compressionForm" enctype="multipart/form-data" method="post" action="/compress">
<label for="file">Select a file:</label>
<input type="file" id="file" name="file" required><br><br>

<label for="compressionType">Select compression type:</label>
<select id="compressionType" name="compressionType" required>
<option value="gzip">GZIP</option>
<option value="deflate">Deflate</option>
<option value="br">Brotli</option>
</select><br><br>

<button type="submit">Compress</button>
</form>
</body>

</html>

0 comments on commit 93b35d8

Please sign in to comment.