Skip to content
Open

bags #235

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"devDependencies": {
"@faker-js/faker": "^8.4.1",
"@mate-academy/eslint-config": "latest",
"@mate-academy/scripts": "^1.8.6",
"@mate-academy/scripts": "^2.1.3",
"axios": "^1.7.2",
"eslint": "^8.57.0",
"eslint-plugin-jest": "^28.6.0",
Expand All @@ -30,5 +30,8 @@
},
"mateAcademy": {
"projectType": "javascript"
},
"dependencies": {
"busboy": "^1.6.0"
}
}
96 changes: 94 additions & 2 deletions src/createServer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,100 @@
/* eslint-disable prettier/prettier */
'use strict';

const http = require('http');
const fs = require('fs');
const path = require('path');
const Busboy = require('busboy');
const zlib = require('zlib');
const { pipeline } = require('stream');

function createServer() {
/* Write your code here */
// Return instance of http.Server class
return http.createServer((req, res) => {
if (req.method === 'GET' && req.url === '/') {
const filePath = path.join(__dirname, 'index.html');

fs.readFile(filePath, (error, content) => {
if (error) {
res.statusCode = 500;

return res.end('Server Error');
}
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(content);
});

return;
}

if (req.method === 'GET' && req.url === '/compress') {
res.statusCode = 400;

return res.end('Bad Request: use POST');
}

if (req.method === 'POST' && req.url === '/compress') {
const bb = Busboy({ headers: req.headers });
let filename = '';
let compressionType = '';
const supportedTypes = {
gzip: { fn: zlib.createGzip, ext: '.gz' },
deflate: { fn: zlib.createDeflate, ext: '.dfl' },
br: { fn: zlib.createBrotliCompress, ext: '.br' },
};

bb.on('field', (name, value) => {
if (name === 'compressionType') {
compressionType = value;
}
});

bb.on('file', (name, file, info) => {
filename = info.filename;

if (name !== 'file') {
res.statusCode = 400;

return res.end('Bad Request: invalid form field');
}

if (!filename) {
res.statusCode = 400;

return res.end('Bad Request: no File');
}

if (!supportedTypes[compressionType]) {
res.statusCode = 400;

return res.end('Bad Request: unsupported compression type');
}

const { fn, ext } = supportedTypes[compressionType];
const compressedName = filename + ext;

res.writeHead(200, {
'Content-Type': 'application/octet-stream',
'Content-Disposition': `attachment; filename="${compressedName}"`,
});
// file.pipe(fn()).pipe(res);

console.log(`file`, file);

Check failure on line 81 in src/createServer.js

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected console statement
console.log('compressionType', compressionType);

Check failure on line 82 in src/createServer.js

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected console statement

pipeline(file, fn(), res, (err) => {
if (err) {
res.statusCode = 500;
res.end('Stream error');
}
});
});
req.pipe(bb);

return;
}
res.statusCode = 404;
res.end('Not Found Data');
});
}

module.exports = {
Expand Down
105 changes: 105 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>File Compressor</title>
</head>

<body
style="
margin: 0;
font-family: Arial, sans-serif;
background: #f5f5f5;
color: #111;
"
>
<div
style="
max-width: 420px;
margin: 100px auto;
padding: 24px;
background: #fff;
border: 1px solid #e5e5e5;
border-radius: 10px;
"
>
<h1 style="font-size: 20px; margin-bottom: 20px; font-weight: 600">
File Compressor
</h1>

<form action="/compress" method="post" enctype="multipart/form-data">
<!-- 1. Сначала compressionType -->
<div style="margin-bottom: 16px">
<label
style="
display: block;
font-size: 12px;
margin-bottom: 6px;
color: #555;
"
>
Compression type
</label>
<select
name="compressionType"
required
style="
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fafafa;
"
>
<option value="gzip">gzip</option>
<option value="deflate">deflate</option>
<option value="br">br</option>
</select>
</div>

<!-- 2. Потом file -->
<div style="margin-bottom: 20px">
<label
style="
display: block;
font-size: 12px;
margin-bottom: 6px;
color: #555;
"
>
File
</label>
<input
type="file"
name="file"
required
style="
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fafafa;
"
/>
</div>

<button
type="submit"
style="
width: 100%;
padding: 10px;
border: none;
border-radius: 6px;
background: #111;
color: #fff;
font-weight: 600;
cursor: pointer;
"
>
Compress file
</button>
</form>
</div>
</body>
</html>
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable prettier/prettier */
/* eslint-disable no-console */
/* Don't change code below */

Expand Down
Loading