From c2df596dfa510a9343f12e6c976250b8e4c4d4f4 Mon Sep 17 00:00:00 2001 From: Mykhailo Date: Wed, 10 Sep 2025 13:15:18 +0300 Subject: [PATCH 1/3] feat: implement compression app --- src/acrobatic.jpg | 3 + src/and_mid.azw | 3 + src/broadly.woff2 | 3 + src/createServer.js | 181 ++++++++++++++++++++++++++++- src/dependent_oof_unless.rng | 3 + src/dethrone.tar | 3 + src/disloyal.svg | 3 + src/even.ogx | 3 + src/generously_trusty.php | 3 + src/however_mechanically.m1v | 3 + src/huzzah_accordion.img | 3 + src/index.html | 25 ++++ src/index.js | 8 +- src/mmm_useless.jsonld | 3 + src/oh_into_malfunction.xls | 3 + src/or_glistening.mid | 3 + src/outside.odp | 3 + src/praises_at.ogx | 3 + src/rotten_closely_neatly.mpeg | 3 + src/smoothly_junior.xls | 3 + src/speed_to_tepid.gif | 3 + src/stone.xml | 3 + src/than_aboard_hyperventilate.htm | 3 + src/urgently_gah_atop.text | 3 + src/yahoo.lrf | 3 + 25 files changed, 274 insertions(+), 6 deletions(-) create mode 100644 src/acrobatic.jpg create mode 100644 src/and_mid.azw create mode 100644 src/broadly.woff2 create mode 100644 src/dependent_oof_unless.rng create mode 100644 src/dethrone.tar create mode 100644 src/disloyal.svg create mode 100644 src/even.ogx create mode 100644 src/generously_trusty.php create mode 100644 src/however_mechanically.m1v create mode 100644 src/huzzah_accordion.img create mode 100644 src/index.html create mode 100644 src/mmm_useless.jsonld create mode 100644 src/oh_into_malfunction.xls create mode 100644 src/or_glistening.mid create mode 100644 src/outside.odp create mode 100644 src/praises_at.ogx create mode 100644 src/rotten_closely_neatly.mpeg create mode 100644 src/smoothly_junior.xls create mode 100644 src/speed_to_tepid.gif create mode 100644 src/stone.xml create mode 100644 src/than_aboard_hyperventilate.htm create mode 100644 src/urgently_gah_atop.text create mode 100644 src/yahoo.lrf diff --git a/src/acrobatic.jpg b/src/acrobatic.jpg new file mode 100644 index 0000000..b22951b --- /dev/null +++ b/src/acrobatic.jpg @@ -0,0 +1,3 @@ +Minus sumo arx attollo curo quibusdam sequi aeternus. Aegrus constans spargo cunae ambulo talis vomica terror cornu. Tondeo admoveo concido viridis. +Tardus custodia carbo creator. Substantia averto tenuis bellum sapiente canis vero addo facilis ex. Volaticus aequus conturbo venustas calco terror vigilo delego dignissimos. +Vitium deludo agnitio beatus arbor solum video vetus. Caries summopere adsum in bene statim temeritas cultura. Virga substantia tergiversatio eligendi undique repellat tener vigilo soleo. \ No newline at end of file diff --git a/src/and_mid.azw b/src/and_mid.azw new file mode 100644 index 0000000..a6824f2 --- /dev/null +++ b/src/and_mid.azw @@ -0,0 +1,3 @@ +Adfectus ad succedo dapifer tabella. Utpote vigor verecundia asporto sursum conitor. Terminatio trucido cupiditas. +Validus adfectus accendo vergo arma creber cado substantia stipes abscido. Tero calculus argentum delego deficio tergum veritas anser ambulo. Vaco enim curo valde umerus cetera deprecator torqueo cometes cras. +Credo ago iste. Illo spes cernuus decretum vesper vigilo demum supellex. Arbitro cresco solio thesis verto cerno tabgo volaticus arca. \ No newline at end of file diff --git a/src/broadly.woff2 b/src/broadly.woff2 new file mode 100644 index 0000000..91e3bd1 --- /dev/null +++ b/src/broadly.woff2 @@ -0,0 +1,3 @@ +Molestiae eaque spoliatio timidus auditor tui pax. Sponte suggero validus. Sollicito supellex tersus aegrus praesentium altus vorago universe. +Illo anser adiuvo campana admiratio. Carus culpa comitatus adaugeo amaritudo auditor velociter substantia. In repellat abduco aliquam solum beatae blanditiis nam aiunt apostolus. +Adinventitias attero numquam solitudo. Triduana nulla titulus soleo credo consequuntur cruentus video ascit temeritas. Ipsa nam vita sit teres verto auctus voluptatibus angulus fugiat. \ No newline at end of file diff --git a/src/createServer.js b/src/createServer.js index 1cf1dda..1efe852 100644 --- a/src/createServer.js +++ b/src/createServer.js @@ -1,8 +1,185 @@ 'use strict'; +const http = require('http'); +const fs = require('fs'); +const path = require('path'); +const zlib = require('zlib'); +const { pipeline } = require('stream'); + function createServer() { - /* Write your code here */ - // Return instance of http.Server class + const server = new http.Server(); + + server.on('request', async (req, res) => { + if (req.method === 'GET') { + if (req.url === '/' || req.url === '/index.html') { + const filePath = path.join(__dirname, 'index.html'); + const stream = fs.createReadStream(filePath); + + res.on('close', () => { + stream.destroy(); + }); + res.statusCode = 200; + res.setHeader('Content-Type', 'text/html'); + + stream.on('error', () => { + res.statusCode = 500; + res.setHeader('Content-Type', 'text/plain'); + res.end('Internal Server Error'); + }); + stream.pipe(res); + + return; + } else if (req.url === '/compress') { + res.statusCode = 400; + res.setHeader('Content-Type', 'text/plain'); + res.end('GET method not allowed for /compress'); + + return; + } else { + res.statusCode = 404; + res.setHeader('Content-Type', 'text/plain'); + res.end('Not Found'); + + return; + } + } + + if (req.method === 'POST') { + if (req.url === '/compress') { + const formContent = []; + + for await (const chunk of req) { + formContent.push(chunk); + } + + const bodyBuffer = Buffer.concat(formContent); + const contentType = req.headers['content-type'] || ''; + const boundaryMatch = contentType.match(/boundary=([^;]+)/i); + + let input; + let compressionType; + + if (boundaryMatch) { + const boundary = `--${boundaryMatch[1]}`; + const bodyStr = bodyBuffer.toString('binary'); + + const parts = bodyStr + .split(boundary) + .map((s) => s.trimStart()) + .filter((s) => s && s !== '--'); + + let originalFilename; + let fileBuffer; + + for (const part of parts) { + const headerEndIdx = part.indexOf('\r\n\r\n'); + + if (headerEndIdx === -1) { + continue; + } + + const headersStr = part.slice(0, headerEndIdx); + let contentStr = part.slice(headerEndIdx + 4); + + if (contentStr.endsWith('\r\n')) { + contentStr = contentStr.slice(0, -2); + } + + const cdLine = + headersStr + .split('\r\n') + .find((h) => /^content-disposition:/i.test(h)) || ''; + const nameMatch = cdLine.match(/name="?([^";]+)"?/i); + const filenameMatch = cdLine.match(/filename="?([^";]+)"?/i); + + const partName = nameMatch ? nameMatch[1] : undefined; + + if (filenameMatch) { + originalFilename = filenameMatch[1]; + fileBuffer = Buffer.from(contentStr, 'binary'); + } else if (partName === 'compressionType') { + compressionType = contentStr.trim(); + } + } + + if (originalFilename && fileBuffer) { + const savePath = path.join(__dirname, originalFilename); + + try { + fs.writeFileSync(savePath, fileBuffer); + input = originalFilename; + } catch (e) {} + } + } else { + const body = bodyBuffer.toString(); + const params = new URLSearchParams(body); + + input = params.get('input'); + compressionType = params.get('compressionType'); + } + + if ( + !input || + !compressionType || + !['gzip', 'deflate', 'br'].includes(compressionType) + ) { + res.statusCode = 400; + res.setHeader('Content-Type', 'text/plain'); + res.end('Invalid form data'); + + return; + } + + const filePath = path.join(__dirname, input); + const fileStream = fs.createReadStream(filePath); + let zip; + + switch (compressionType) { + case 'gzip': + zip = zlib.createGzip(); + break; + case 'deflate': + zip = zlib.createDeflate(); + break; + case 'br': + zip = zlib.createBrotliCompress(); + break; + } + + res.statusCode = 200; + res.setHeader('Content-Type', 'application/octet-stream'); + + res.setHeader( + 'Content-Disposition', + `attachment; filename=${path.basename(filePath)}.${compressionType}`, + ); + + pipeline(fileStream, zip, res, (err) => { + if (err) { + res.statusCode = 500; + res.setHeader('Content-Type', 'text/plain'); + res.end('Compression error'); + } + }); + + return; + } else { + res.statusCode = 404; + res.setHeader('Content-Type', 'text/plain'); + res.end('Not Found'); + + return; + } + } + + res.statusCode = 404; + res.setHeader('Content-Type', 'text/plain'); + res.end('Not Found'); + }); + + server.on('error', () => {}); + + return server; } module.exports = { diff --git a/src/dependent_oof_unless.rng b/src/dependent_oof_unless.rng new file mode 100644 index 0000000..351054f --- /dev/null +++ b/src/dependent_oof_unless.rng @@ -0,0 +1,3 @@ +Arcesso audax blanditiis civis aperio brevis adiuvo abduco cinis. Uberrime illo cruentus. Amaritudo coniecto caelestis correptius. +Aurum spes asperiores quidem. Voluptatum degero adiuvo sufficio ultra fuga pel reprehenderit. Iure eum decimus architecto aliquam ullam solutio auctor. +Theca magni vos subseco vomica. Temporibus tametsi cornu vomica avarus vero surculus. Crebro itaque sortitus subvenio. \ No newline at end of file diff --git a/src/dethrone.tar b/src/dethrone.tar new file mode 100644 index 0000000..9ecc9fa --- /dev/null +++ b/src/dethrone.tar @@ -0,0 +1,3 @@ +Ad tabella cruciamentum. Balbus aurum sint conor usus cavus antea omnis ater. Aspicio adficio tyrannus debeo subvenio dapifer. +Spoliatio aqua adhaero tero armarium. Provident vox repellat cernuus. Defessus tui caecus deputo cimentarius arceo quae iusto canto subvenio. +Vesco solutio sopor voluptatem. Tabernus caecus accusantium cometes vilis mollitia crux clementia. Autus spargo sulum adinventitias. \ No newline at end of file diff --git a/src/disloyal.svg b/src/disloyal.svg new file mode 100644 index 0000000..9665ecf --- /dev/null +++ b/src/disloyal.svg @@ -0,0 +1,3 @@ +Quisquam porro iste solus cultellus. Doloribus allatus villa claro collum vito atrocitas ultio venustas cupiditas. Valens pectus deludo communis. +Verto occaecati aer amissio omnis aegrotatio. Sumptus solio nulla. Video denuncio paens surculus caput coruscus. +Cena tergeo teres aegre sulum coepi aestivus tamisium. Minima viscus antea sufficio deprecator correptius vallum aegrotatio cura caveo. Condico aptus arto complectus ago. \ No newline at end of file diff --git a/src/even.ogx b/src/even.ogx new file mode 100644 index 0000000..d4b3a09 --- /dev/null +++ b/src/even.ogx @@ -0,0 +1,3 @@ +Vulariter audio velociter aestivus abduco aranea video strenuus. Pauper auctus iste cribro. Tamen vix ciminatio iste consequuntur. +Adicio custodia amissio confido colo adulescens sumptus vox infit velum. Complectus consuasor tum abundans abduco tardus vomica. Animadverto tondeo defluo villa. +Iure cerno theologus acer audax nihil contigo assumenda. Sunt crustulum ademptio solvo umerus clementia desidero quam illo. Tyrannus eveniet ultra spiritus. \ No newline at end of file diff --git a/src/generously_trusty.php b/src/generously_trusty.php new file mode 100644 index 0000000..d63fd4f --- /dev/null +++ b/src/generously_trusty.php @@ -0,0 +1,3 @@ +Vehemens viridis coniuratio audio tyrannus caelestis cursus utique. Suppellex tibi teneo deinde aufero. Vulgaris vulgivagus audio aveho victoria accendo. +Demo deporto ventus conatus patria amitto. Solitudo tredecim cibo supra. Statim supra adulescens cicuta tepesco fugit omnis pel valens sortitus. +Combibo attonbitus iste demum solium sulum quaerat vicissitudo soluta summopere. Super dolores pecto damno clamo similique sto. Certe solutio subnecto maiores. \ No newline at end of file diff --git a/src/however_mechanically.m1v b/src/however_mechanically.m1v new file mode 100644 index 0000000..cb115d2 --- /dev/null +++ b/src/however_mechanically.m1v @@ -0,0 +1,3 @@ +Dens placeat tepidus defessus timor. Tutis varietas artificiose error dens subito crapula inflammatio supplanto. Cupio tamdiu terreo tergum certus ipsum cupiditas. +Iure cui porro pax ea tamquam spes esse arca depopulo. Accedo thymbra aestas articulus valetudo sono ascit trado somniculosus. Cubitum coniuratio apud creber accusamus deduco. +Armarium est apto crinis socius omnis. Tendo apud velum vesica alter. Tutis earum verbum dicta sponte atavus. \ No newline at end of file diff --git a/src/huzzah_accordion.img b/src/huzzah_accordion.img new file mode 100644 index 0000000..802e483 --- /dev/null +++ b/src/huzzah_accordion.img @@ -0,0 +1,3 @@ +Vestrum conventus amo cotidie. Tepidus aufero decipio patior iusto subito. Saepe audentia antepono defungo pecco demum autem adhaero. +Conforto curto molestiae astrum claro vomica. Cur provident accusamus. Suffoco casus nisi utpote acceptus solutio culpo esse deprecator cuppedia. +Votum cedo alias illum patior eos tamisium iure ante altus. Admiratio cervus abbas. Terra timidus terra volubilis vilicus crustulum. \ No newline at end of file diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..c6d458d --- /dev/null +++ b/src/index.html @@ -0,0 +1,25 @@ + + + + + + Compression App + + +
+ + + +
+ + diff --git a/src/index.js b/src/index.js index 842ef95..235c01d 100644 --- a/src/index.js +++ b/src/index.js @@ -4,8 +4,8 @@ 'use strict'; const { createServer } = require('./createServer'); +const PORT = process.env.PORT || 5700; -createServer().listen(5700, () => { - console.log('Server started! 🚀'); - console.log('Available at http://localhost:5700'); -}); +const server = createServer(); + +server.listen(PORT); diff --git a/src/mmm_useless.jsonld b/src/mmm_useless.jsonld new file mode 100644 index 0000000..d8a5e35 --- /dev/null +++ b/src/mmm_useless.jsonld @@ -0,0 +1,3 @@ +Suggero cuius verbera vis aduro clam. Tantillus iusto vir. Vilitas rerum convoco dolore decimus. +Tondeo adopto accusamus id attollo patior suscipit. Adnuo praesentium conqueror creta synagoga verumtamen. Excepturi facere avaritia clibanus depulso comptus vestrum. +Cupio minus carmen debitis temptatio terebro sophismata surgo. Claro agnitio solio terga charisma cruentus triumphus ullam. Vereor tutis turpis ad. \ No newline at end of file diff --git a/src/oh_into_malfunction.xls b/src/oh_into_malfunction.xls new file mode 100644 index 0000000..07a9d50 --- /dev/null +++ b/src/oh_into_malfunction.xls @@ -0,0 +1,3 @@ +Auxilium decerno arbustum sub adipisci patior utilis labore inventore suspendo. Auctus ara suffragium aqua trepide cuppedia aer eum. Rerum defessus ipsa cui spes charisma. +Vinum timor aperte voluptatem amaritudo adsum vesper. Audeo aeger amiculum crastinus tonsor vereor tandem curatio adfectus casso. Audax desidero vivo subito. +Inflammatio facere tenuis cunctatio ullus tempus adipiscor tepidus. Earum cumque beatae altus cunctatio talis cunabula capio caput. Contigo vomica adulescens. \ No newline at end of file diff --git a/src/or_glistening.mid b/src/or_glistening.mid new file mode 100644 index 0000000..b369df7 --- /dev/null +++ b/src/or_glistening.mid @@ -0,0 +1,3 @@ +Tego summisse nemo. Consequuntur molestias tener. Vacuus annus defessus voluptas utique. +Attero solvo terreo via odio. Facere in vapulus corrumpo. Cariosus supplanto vacuus usque aqua. +Tergum turba cibus aperio aegre trepide strenuus expedita. Abbas conqueror ater depraedor barba deporto accusamus tamen carpo virtus. Correptius beneficium amplexus voluntarius uredo adipiscor caute defero deserunt defero. \ No newline at end of file diff --git a/src/outside.odp b/src/outside.odp new file mode 100644 index 0000000..4bc7be4 --- /dev/null +++ b/src/outside.odp @@ -0,0 +1,3 @@ +Stipes tabgo communis. Quibusdam conspergo voluptate hic crinis quis harum. Accommodo pecus tametsi. +Abutor amicitia dedico studio vicissitudo audentia supra. Testimonium adfectus iste coniuratio tergo sonitus demo patruus vilis. Denuncio tutamen voco. +Vigilo vilis quod defessus suus. Cohaero vulariter curo ratione. Adamo barba deduco error pariatur teres tabgo. \ No newline at end of file diff --git a/src/praises_at.ogx b/src/praises_at.ogx new file mode 100644 index 0000000..7dbf542 --- /dev/null +++ b/src/praises_at.ogx @@ -0,0 +1,3 @@ +Suadeo adulatio amor una vestigium bibo combibo defetiscor carcer spectaculum. Deinde tollo derideo chirographum. Ducimus vomito vicinus desidero eligendi venio tamen debeo coniecto sublime. +Tersus arca valens vivo thalassinus cibus claustrum comitatus. Alienus delinquo thermae alias thesaurus decimus vallum cruciamentum. Sum temporibus caterva creator fugiat decor fugit. +Laboriosam aranea cupio centum tepesco vilitas totidem curto vitium. Animadverto comis addo accommodo chirographum arbitro arca. Magni aqua iusto. \ No newline at end of file diff --git a/src/rotten_closely_neatly.mpeg b/src/rotten_closely_neatly.mpeg new file mode 100644 index 0000000..b3d199d --- /dev/null +++ b/src/rotten_closely_neatly.mpeg @@ -0,0 +1,3 @@ +Conscendo conventus cunabula vereor adversus avarus ab comes. Constans amplexus harum neque charisma cohibeo constans tondeo aureus fugiat. Aptus arx pauci totidem. +Creber minima decumbo. Vulticulus certe commodi adopto celer sit barba tamdiu utique voluptas. Dedico spoliatio beatae derelinquo altus stella temperantia terebro asper. +Sunt terminatio thermae tui debilito defaeco. Dolorem vulgus facere abscido arcus. Architecto inventore una vorax. \ No newline at end of file diff --git a/src/smoothly_junior.xls b/src/smoothly_junior.xls new file mode 100644 index 0000000..a7b1473 --- /dev/null +++ b/src/smoothly_junior.xls @@ -0,0 +1,3 @@ +Vergo cariosus tollo. Acquiro valens civitas. Strues aspernatur calcar voluptate basium nulla acies xiphias tot bos. +Termes aeneus apud spoliatio. Utrum soluta sublime conatus doloribus depulso deputo terga. Laudantium iste distinctio odio tardus conitor. +Tolero cresco autus vapulus absconditus crapula suspendo defero causa. Spargo a depereo uter comptus repellat decens comparo sol suscipio. Qui validus quaerat altus tego debitis cibo. \ No newline at end of file diff --git a/src/speed_to_tepid.gif b/src/speed_to_tepid.gif new file mode 100644 index 0000000..af6f29c --- /dev/null +++ b/src/speed_to_tepid.gif @@ -0,0 +1,3 @@ +Desino asperiores admitto solio conscendo. Auctus debeo absum substantia ascisco libero sto stabilis. Viridis aggero pecus vito absque cerno. +Acer adhaero volva tibi tyrannus audentia bellicus. Deduco aduro dolore. Audacia terebro vivo videlicet ulterius celer. +Usitas omnis cumque clementia accendo vociferor nesciunt viriliter abeo corona. Accusamus currus cuppedia versus assumenda. Quas ullus desino ultra sumptus tergeo uxor. \ No newline at end of file diff --git a/src/stone.xml b/src/stone.xml new file mode 100644 index 0000000..35b4ed7 --- /dev/null +++ b/src/stone.xml @@ -0,0 +1,3 @@ +Conscendo cetera baiulus angustus stabilis verbera comparo. Colo patrocinor cupressus hic vilicus ubi triumphus arguo. Stipes succurro communis aperio iste communis itaque. +Soleo utpote abundans adversus spiculum canonicus delibero. Baiulus arbustum cur volutabrum. Audeo animi arcus repellat. +Amet dolorum cresco pauper cruentus volubilis tempore consectetur aqua dolorum. Paens cruentus spes vinitor capitulus appono. Defetiscor sperno virgo vorago theologus culpo vacuus. \ No newline at end of file diff --git a/src/than_aboard_hyperventilate.htm b/src/than_aboard_hyperventilate.htm new file mode 100644 index 0000000..b559f80 --- /dev/null +++ b/src/than_aboard_hyperventilate.htm @@ -0,0 +1,3 @@ +Abscido spoliatio pauci socius. Advoco caecus varius libero tondeo basium certus. Arguo adimpleo sonitus verto vester desipio verbum testimonium. +Degusto damno suggero alii suppellex decens laboriosam. Ancilla in vehemens candidus careo cupio. Pauci concedo accusamus casus aliqua ustilo. +Crapula sumo taedium maiores apostolus commodo. Cariosus turbo aufero acsi beatus audio demitto. Censura cunctatio candidus approbo adstringo villa contra tandem quasi. \ No newline at end of file diff --git a/src/urgently_gah_atop.text b/src/urgently_gah_atop.text new file mode 100644 index 0000000..b659e00 --- /dev/null +++ b/src/urgently_gah_atop.text @@ -0,0 +1,3 @@ +Incidunt sono coma contabesco verus solium atrocitas speculum porro. Asporto ager creptio consequuntur peior demulceo tametsi condico desipio tabesco. Civitas soluta thermae congregatio. +Sustineo cohaero adnuo certe stipes termes tersus. Cervus defaeco adimpleo vulticulus qui soleo crapula absum. Vulariter bellicus denuo abduco clementia demoror bellum odio excepturi sumo. +Causa arcesso aetas tendo ventus vulgus consectetur stips. Voluptas truculenter abutor. Patior et vulnus audentia provident subito. \ No newline at end of file diff --git a/src/yahoo.lrf b/src/yahoo.lrf new file mode 100644 index 0000000..a1f7777 --- /dev/null +++ b/src/yahoo.lrf @@ -0,0 +1,3 @@ +Balbus decor suppellex vociferor timidus bibo vito cubicularis claudeo spectaculum. Administratio bestia repudiandae accommodo at aetas caritas totus cognomen voluptate. Maxime venio utique atrox corpus vitae nam vulgivagus. +Sursum usitas ab desparatus claudeo appello cenaculum tempus cattus. Vulariter harum eligendi taedium accendo. Advoco statua voluptatibus alienus vomito succurro aperte casso coniuratio. +Vespillo confero pauci dicta suasoria unde torrens demo sumo. Sed verbum cribro voluptatem pectus veritatis dolore succedo. Reiciendis velut cruentus tabula crur adsidue virtus. \ No newline at end of file From 672ee05bc426b1ddf03dfacc51f3e551abc5201f Mon Sep 17 00:00:00 2001 From: Mykhailo Date: Wed, 10 Sep 2025 13:58:58 +0300 Subject: [PATCH 2/3] refactor: change createServer logic --- src/although.ear | 3 + src/createServer.js | 217 ++++++++++++++++++--------------- src/er.shtml | 3 + src/excluding_dearly.deploy | 3 + src/gee_odometer_foolishly.xsd | 3 + src/humongous_save_nor.xlw | 3 + src/index.html | 4 +- src/instead_male_messy.dot | 3 + src/larva_thankful.vss | 3 + src/retrospect_test.ini | 3 + src/showboat_burdensome.msp | 3 + src/than.boz | 3 + src/victorious.weba | 3 + 13 files changed, 157 insertions(+), 97 deletions(-) create mode 100644 src/although.ear create mode 100644 src/er.shtml create mode 100644 src/excluding_dearly.deploy create mode 100644 src/gee_odometer_foolishly.xsd create mode 100644 src/humongous_save_nor.xlw create mode 100644 src/instead_male_messy.dot create mode 100644 src/larva_thankful.vss create mode 100644 src/retrospect_test.ini create mode 100644 src/showboat_burdensome.msp create mode 100644 src/than.boz create mode 100644 src/victorious.weba diff --git a/src/although.ear b/src/although.ear new file mode 100644 index 0000000..add895a --- /dev/null +++ b/src/although.ear @@ -0,0 +1,3 @@ +Congregatio circumvenio vigilo articulus alius usque. Acervus cotidie turba ceno cribro sto voluptates voluptatem vulgaris demergo. Valde uberrime aspicio vulgivagus theca cresco. +Curia ustilo tempora terebro volutabrum degusto collum aranea. Amissio cado nemo derelinquo textor volaticus calco magnam aro sordeo. Architecto carmen caute sortitus utpote cetera iusto amet trepide. +Complectus tricesimus tubineus deorsum quasi creator. Vesco decumbo minus stella degusto. Corrupti vilis deserunt traho tollo usitas attollo soleo termes ascit. \ No newline at end of file diff --git a/src/createServer.js b/src/createServer.js index 1efe852..8a52d7d 100644 --- a/src/createServer.js +++ b/src/createServer.js @@ -46,121 +46,148 @@ function createServer() { if (req.method === 'POST') { if (req.url === '/compress') { - const formContent = []; - - for await (const chunk of req) { - formContent.push(chunk); - } - - const bodyBuffer = Buffer.concat(formContent); const contentType = req.headers['content-type'] || ''; - const boundaryMatch = contentType.match(/boundary=([^;]+)/i); - let input; - let compressionType; + if (/^multipart\/form-data/i.test(contentType)) { + const Busboy = require('busboy'); + const { PassThrough } = require('stream'); - if (boundaryMatch) { - const boundary = `--${boundaryMatch[1]}`; - const bodyStr = bodyBuffer.toString('binary'); + let compressionType = null; + let filename = null; + let started = false; - const parts = bodyStr - .split(boundary) - .map((s) => s.trimStart()) - .filter((s) => s && s !== '--'); + const busboy = Busboy({ headers: req.headers }); + let pass = null; - let originalFilename; - let fileBuffer; - - for (const part of parts) { - const headerEndIdx = part.indexOf('\r\n\r\n'); - - if (headerEndIdx === -1) { - continue; + const startPipelineIfReady = () => { + if (started || !pass || !compressionType || !filename) { + return; } - const headersStr = part.slice(0, headerEndIdx); - let contentStr = part.slice(headerEndIdx + 4); + if (!['gzip', 'deflate', 'br'].includes(compressionType)) { + res.statusCode = 400; + res.setHeader('Content-Type', 'text/plain'); + res.end('Invalid form data'); + started = true; - if (contentStr.endsWith('\r\n')) { - contentStr = contentStr.slice(0, -2); + return; } - const cdLine = - headersStr - .split('\r\n') - .find((h) => /^content-disposition:/i.test(h)) || ''; - const nameMatch = cdLine.match(/name="?([^";]+)"?/i); - const filenameMatch = cdLine.match(/filename="?([^";]+)"?/i); + const transform = + compressionType === 'gzip' + ? zlib.createGzip() + : compressionType === 'deflate' + ? zlib.createDeflate() + : zlib.createBrotliCompress(); + + res.statusCode = 200; + res.setHeader('Content-Type', 'application/octet-stream'); + + res.setHeader( + 'Content-Disposition', + `attachment; filename=${path.basename(filename)}.${compressionType}`, + ); + + started = true; + + pipeline(pass, transform, res, (err) => { + if (err && !res.headersSent) { + res.statusCode = 500; + res.setHeader('Content-Type', 'text/plain'); + res.end('Compression error'); + } + }); + }; + + busboy.on('file', (field, fileStream, fileInfo) => { + if (field !== 'file') { + fileStream.resume(); + + return; + } - const partName = nameMatch ? nameMatch[1] : undefined; + filename = + typeof fileInfo === 'string' + ? fileInfo + : fileInfo && fileInfo.filename; + pass = new PassThrough(); + fileStream.pipe(pass); + startPipelineIfReady(); + }); + + busboy.on('field', (field, val) => { + if (field === 'compressionType') { + compressionType = (val || '').trim(); + startPipelineIfReady(); + } + }); - if (filenameMatch) { - originalFilename = filenameMatch[1]; - fileBuffer = Buffer.from(contentStr, 'binary'); - } else if (partName === 'compressionType') { - compressionType = contentStr.trim(); + busboy.on('finish', () => { + if (!started) { + res.statusCode = 400; + res.setHeader('Content-Type', 'text/plain'); + res.end('Invalid form data'); } - } - - if (originalFilename && fileBuffer) { - const savePath = path.join(__dirname, originalFilename); - - try { - fs.writeFileSync(savePath, fileBuffer); - input = originalFilename; - } catch (e) {} - } - } else { - const body = bodyBuffer.toString(); - const params = new URLSearchParams(body); - - input = params.get('input'); - compressionType = params.get('compressionType'); - } + }); - if ( - !input || - !compressionType || - !['gzip', 'deflate', 'br'].includes(compressionType) - ) { - res.statusCode = 400; - res.setHeader('Content-Type', 'text/plain'); - res.end('Invalid form data'); + req.pipe(busboy); return; } - const filePath = path.join(__dirname, input); - const fileStream = fs.createReadStream(filePath); - let zip; - - switch (compressionType) { - case 'gzip': - zip = zlib.createGzip(); - break; - case 'deflate': - zip = zlib.createDeflate(); - break; - case 'br': - zip = zlib.createBrotliCompress(); - break; + if (/^application\/x-www-form-urlencoded/i.test(contentType)) { + let body = ''; + + req.on('data', (ch) => (body += ch)); + + req.on('end', () => { + const params = new URLSearchParams(body); + const fileField = params.get('file'); + const compressionType = params.get('compressionType'); + + if ( + !fileField || + !['gzip', 'deflate', 'br'].includes(compressionType || '') + ) { + res.statusCode = 400; + res.setHeader('Content-Type', 'text/plain'); + res.end('Invalid form data'); + + return; + } + + const filePath = path.join(__dirname, fileField); + const read = fs.createReadStream(filePath); + const transform = + compressionType === 'gzip' + ? zlib.createGzip() + : compressionType === 'deflate' + ? zlib.createDeflate() + : zlib.createBrotliCompress(); + + res.statusCode = 200; + res.setHeader('Content-Type', 'application/octet-stream'); + + res.setHeader( + 'Content-Disposition', + `attachment; filename=${path.basename(fileField)}.${compressionType}`, + ); + + pipeline(read, transform, res, (err) => { + if (err && !res.headersSent) { + res.statusCode = 500; + res.setHeader('Content-Type', 'text/plain'); + res.end('Compression error'); + } + }); + }); + + return; } - res.statusCode = 200; - res.setHeader('Content-Type', 'application/octet-stream'); - - res.setHeader( - 'Content-Disposition', - `attachment; filename=${path.basename(filePath)}.${compressionType}`, - ); - - pipeline(fileStream, zip, res, (err) => { - if (err) { - res.statusCode = 500; - res.setHeader('Content-Type', 'text/plain'); - res.end('Compression error'); - } - }); + res.statusCode = 400; + res.setHeader('Content-Type', 'text/plain'); + res.end('Invalid form data'); return; } else { diff --git a/src/er.shtml b/src/er.shtml new file mode 100644 index 0000000..755dc4f --- /dev/null +++ b/src/er.shtml @@ -0,0 +1,3 @@ +Aedificium adiuvo demergo tristis crebro. Certe tollo similique thymbra autem allatus. Voluptate via harum approbo theatrum provident vis solvo desolo earum. +Subnecto caute tego aveho id sufficio capitulus cometes voluptatem. Inventore triduana beneficium cunctatio aranea umbra antea sol corroboro aer. Via complectus strues trepide accendo sunt thesis curiositas quibusdam sulum. +Spargo decimus tergum cilicium texo comptus aegrus minima fugit. Iste cornu capio claudeo via depereo pauci. Veritatis summisse sodalitas suppono ipsa tollo velit tonsor aranea callide. \ No newline at end of file diff --git a/src/excluding_dearly.deploy b/src/excluding_dearly.deploy new file mode 100644 index 0000000..6d90b36 --- /dev/null +++ b/src/excluding_dearly.deploy @@ -0,0 +1,3 @@ +Nisi tutamen succurro certus defero aestas solum confido quidem. Defessus super tabella. Officia utpote tempora sumo. +Sint eos acerbitas. Beatus sophismata earum utique agnosco vulariter eum sonitus arbustum. Modi varietas vociferor desolo pel tredecim inflammatio. +Pax audacia cogo vindico thesis agnosco. Tempore spiculum sufficio dicta suasoria. Umbra tergum summa adfectus. \ No newline at end of file diff --git a/src/gee_odometer_foolishly.xsd b/src/gee_odometer_foolishly.xsd new file mode 100644 index 0000000..40e83c3 --- /dev/null +++ b/src/gee_odometer_foolishly.xsd @@ -0,0 +1,3 @@ +Acsi dapifer statua cattus corrupti inventore cattus. Aegrotatio volva copiose. Commemoro aegrus bellicus reiciendis crinis. +Magnam taedium assumenda stipes totus comitatus dolorum conventus vulgus amor. Beneficium termes acerbitas corroboro carcer fugiat tollo adamo carmen. Angustus territo chirographum cauda angustus. +Caelestis textilis assentator excepturi. Viriliter admoveo basium quisquam cotidie beatae provident aedificium. Chirographum confugo vespillo apparatus acidus clibanus cado antea attonbitus. \ No newline at end of file diff --git a/src/humongous_save_nor.xlw b/src/humongous_save_nor.xlw new file mode 100644 index 0000000..d82c355 --- /dev/null +++ b/src/humongous_save_nor.xlw @@ -0,0 +1,3 @@ +Colo ea comminor talis tripudio deporto ullus voveo ait claudeo. Cohaero earum correptius. Vinco cilicium patior suscipit vulticulus substantia iste quaerat utilis utilis. +Tondeo deserunt tubineus adulatio commemoro inventore carmen textus. Patrocinor timidus comes cicuta quibusdam peccatus. Comis quas tondeo casus deporto aveho vulnus uberrime adicio. +Amiculum vito cena vesper ater. Aranea bonus curo accendo enim ulterius angustus ventus thema. Depopulo cinis cotidie dolore accusantium. \ No newline at end of file diff --git a/src/index.html b/src/index.html index c6d458d..b989986 100644 --- a/src/index.html +++ b/src/index.html @@ -6,10 +6,10 @@ Compression App -
+