Skip to content

create 4-all file #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
22 changes: 22 additions & 0 deletions JavaScript/4-all/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Вопросы

- Зачем нужно объявлять константу STATIC_FILE_LENGTH?
- Как вызвать pathTraversal что бы он был равен true?
- Можно ли утверждать, чем больше проверок на безопасность тем лучше,
или в некоторых случаях они создают уязвимость?

## Упражнения

1. Обработайте ошибки:

- когда файла не найден; ✓
- когда нет прав на чтение файла или каталога; ✗
- когда происходит попытка чтения файла из каталога выше. ✗

2. Создайте шаблоны страниц с ошибками в специальном каталоге. ✓
3. Перепишите те места, которые возможно с использованием `fs.promises`. ✓
4. Объедините все примеры в один: ✓

- отдача индекса каталога; ✓
- кеширование; ✓
- обработка ошибок. ✓
86 changes: 86 additions & 0 deletions JavaScript/4-all/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
'use strict';

const http = require('node:http');
const fs = require('node:fs').promises;
const path = require('node:path');

const PORT = 8000;

const STATIC_PATH = path.join(process.cwd(), './static');

const MIME_TYPE = {
default: 'application/octet-stream',
html: 'text/html; charset=UTF-8',
js: 'application/javascript; charset=UTF-8',
css: 'text/css',
png: 'image/png',
jpg: 'image/jpeg',
ico: 'image/x-icon',
};

const cache = new Map();

const cacheFile = async (filePath) => {
const key = filePath.substring(STATIC_PATH.length).replace(/\\/g, '/');
const value = await fs.readFile(filePath);
cache.set(key, value);
};

const cacheDirectory = async (directoryPath) => {
const files = await fs.readdir(directoryPath, { withFileTypes: true });
for (const file of files) {
const filePath = path.join(file.path, file.name);
if (file.isDirectory()) cacheDirectory(filePath);
else cacheFile(filePath);
}
const key = directoryPath.substring(STATIC_PATH.length).replace(/\\/g, '/');
cache.set(
key || '/',
files.map((file) => file.name)
);
};

cacheDirectory(STATIC_PATH);

const folderIndex = (url) => {
const items = cache.get(url);
if (url !== '/' && items[0] !== '../') items.unshift('../');
const list = items
.map((el) => {
const addres = path.join(url, el);
return `<li><a href="http://localhost:${PORT}${addres}">${el}</a></li>`;
})
.join('\n');
const file = `<h2>Directory files: <h2> <ul>${list}</ul>`;
return file;
};

const prepareFile = (url) => {
const filePath = path.join(STATIC_PATH, url);
const pathTraversal = !filePath.startsWith(STATIC_PATH);
// console.log(pathTraversal)
const exists = cache.get(url);
const found = !pathTraversal && !!exists;
let cachePath = url;
if (!found) cachePath = '/errors/404.html';
if (pathTraversal) cachePath = '/errors/traversal.html'; // Не знаю как установить true через браузер
if (!'readingRights') cachePath = '/errors/no-reading.html'; // Не представляю как это раелизовать без авторизации пользователя
const errorPath =
cachePath.startsWith('/errors/') && cachePath.endsWith('.html');
const isDirectory = exists instanceof Array && !errorPath;
const ext = path.extname(cachePath).substring(1);
const content = isDirectory ? folderIndex(cachePath) : cache.get(cachePath);
return { found, ext: isDirectory ? 'html' : ext, content };
};

http
.createServer((req, res) => {
const file = prepareFile(req.url);
const mimeType = MIME_TYPE[file.ext] || MIME_TYPE.default;
const statusCode = file.found ? 200 : 404;
res.writeHead(statusCode, { 'content-type': mimeType });
res.end(file.content);
})
.listen(PORT, () =>
console.log(`Server is running: http://localhost:${PORT}`)
);
1 change: 1 addition & 0 deletions JavaScript/4-all/static/errors/404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h2>file is not exists!</h2>
1 change: 1 addition & 0 deletions JavaScript/4-all/static/errors/no-reading.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h2>You do not have permission to read this directory!</h2>
1 change: 1 addition & 0 deletions JavaScript/4-all/static/errors/traversal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Occurrd traversal path!</h1>
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added JavaScript/4-all/static/images/Diophant.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added JavaScript/4-all/static/images/channel-xyz.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions JavaScript/4-all/static/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>Document</title>
<link rel="stylesheet" href="styles/style.css" />
</head>
<body>
<button class="hello">hello</button>
</body>
</html>
1 change: 1 addition & 0 deletions JavaScript/4-all/static/js/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('hello');
6 changes: 6 additions & 0 deletions JavaScript/4-all/static/styles/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.hello {
background-color: black;
width: 200;
height: 60;
color: white;
}