From 04515d5ca5b1300ab5ca6bf960538405b8c936d1 Mon Sep 17 00:00:00 2001 From: Dmitrii Damyan Date: Thu, 2 Apr 2026 22:58:12 +0300 Subject: [PATCH 1/2] Solution --- src/createServer.js | 121 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 2 deletions(-) diff --git a/src/createServer.js b/src/createServer.js index 1cf1dda..a4ef594 100644 --- a/src/createServer.js +++ b/src/createServer.js @@ -1,8 +1,125 @@ 'use strict'; +/* eslint-disable no-console */ + +const http = require('node:http'); +const fs = require('node:fs'); +const path = require('node:path'); + +const mimeTypes = { + '.html': 'text/html; charset=utf-8', + '.htm': 'text/html; charset=utf-8', + '.css': 'text/css; charset=utf-8', + '.js': 'application/javascript; charset=utf-8', + '.json': 'application/json; charset=utf-8', + '.png': 'image/png', + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.gif': 'image/gif', + '.svg': 'image/svg+xml', + '.ico': 'image/x-icon', + '.txt': 'text/plain; charset=utf-8', +}; + +function getContentType(filePath) { + const ext = path.extname(filePath).toLowerCase(); + + return mimeTypes[ext] || 'application/octet-stream'; +} + +function readFile(pathToFile, res, contentType) { + fs.readFile(pathToFile, (error, data) => { + if (error) { + if (error.code === 'ENOENT') { + res.statusCode = 404; + res.setHeader('Content-Type', 'text/plain'); + res.end('Not found'); + } else { + res.statusCode = 500; + res.setHeader('Content-Type', 'text/plain'); + res.end('Server error'); + } + + return; + } + res.statusCode = 200; + res.setHeader('Content-Type', contentType); + res.end(data); + }); +} function createServer() { - /* Write your code here */ - // Return instance of http.Server class + const server = http.createServer((req, res) => { + const { pathname } = new URL(req.url, 'http://localhost:5701'); + + if (pathname === '/favicon.ico') { + res.statusCode = 204; + res.setHeader('Content-Type', 'text/plain'); + res.end(); + + return; + } + + // const decodedPath = decodeURIComponent(pathname); + + // if (decodedPath.includes('..')) { + // res.statusCode = 400; + // res.setHeader('Content-Type', 'text/plain'); + // res.end('Not Found'); + + // return; + // } + if (req.url.includes('..')) { + res.statusCode = 400; + res.setHeader('Content-Type', 'text/plain'); + res.end(); // или просто res.end() 'Bad Request' + + return; + } + + if (pathname.includes('//')) { + res.statusCode = 404; + res.setHeader('Content-Type', 'text/plain'); + res.end('Not Found'); + + return; + } + + if (pathname === '/file' || pathname === '/file/') { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/plain'); + res.end('To upload a file, use the path /file/'); + + return; + } + + if (!pathname.startsWith('/file')) { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/plain'); + res.end('To upload a file, use the path /file/'); + + return; + } + + const requested = pathname.replace(/^\/file/, '').replace(/^\/+/, ''); + + const publicDir = path.normalize( + path.join(__dirname, '..', 'public') + path.sep, + ); + + const fullPath = path.normalize(path.join(publicDir, requested)); + + if (!fullPath.startsWith(publicDir)) { + res.statusCode = 400; + res.setHeader('Content-Type', 'text/plain'); + res.end('Not Found'); + + return; + } + + readFile(fullPath, res, getContentType(fullPath)); + }); + + return server; } module.exports = { From 8128b5dd4bff5bbde0b45f1681a8085ef2ad8c90 Mon Sep 17 00:00:00 2001 From: Dmitrii Damyan Date: Fri, 3 Apr 2026 15:43:35 +0300 Subject: [PATCH 2/2] add solution --- src/createServer.js | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/createServer.js b/src/createServer.js index a4ef594..7faf21f 100644 --- a/src/createServer.js +++ b/src/createServer.js @@ -6,27 +6,29 @@ const fs = require('node:fs'); const path = require('node:path'); const mimeTypes = { - '.html': 'text/html; charset=utf-8', - '.htm': 'text/html; charset=utf-8', - '.css': 'text/css; charset=utf-8', - '.js': 'application/javascript; charset=utf-8', - '.json': 'application/json; charset=utf-8', + '.html': 'text/html', + '.htm': 'text/html', + '.css': 'text/css', + '.js': 'application/javascript', + '.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.svg': 'image/svg+xml', '.ico': 'image/x-icon', - '.txt': 'text/plain; charset=utf-8', + '.txt': 'text/plain', }; +// ; charset=utf-8 + function getContentType(filePath) { const ext = path.extname(filePath).toLowerCase(); return mimeTypes[ext] || 'application/octet-stream'; } -function readFile(pathToFile, res, contentType) { +function readFile(pathToFile, res, contentType = 'text/plain') { fs.readFile(pathToFile, (error, data) => { if (error) { if (error.code === 'ENOENT') { @@ -59,19 +61,12 @@ function createServer() { return; } - // const decodedPath = decodeURIComponent(pathname); - - // if (decodedPath.includes('..')) { - // res.statusCode = 400; - // res.setHeader('Content-Type', 'text/plain'); - // res.end('Not Found'); + const decodedPath = decodeURIComponent(pathname); - // return; - // } - if (req.url.includes('..')) { + if (decodedPath.includes('..')) { res.statusCode = 400; res.setHeader('Content-Type', 'text/plain'); - res.end(); // или просто res.end() 'Bad Request' + res.end('Not Found'); return; } @@ -79,15 +74,18 @@ function createServer() { if (pathname.includes('//')) { res.statusCode = 404; res.setHeader('Content-Type', 'text/plain'); - res.end('Not Found'); + res.end('Bad Request'); return; } if (pathname === '/file' || pathname === '/file/') { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/plain'); - res.end('To upload a file, use the path /file/'); + const pathTopublicDir = path.normalize( + path.join(__dirname, '..', 'public') + path.sep, + ); + const newPath = path.join(pathTopublicDir, 'index.html'); + + readFile(newPath, res, 'text/plain'); return; }