370 行
10 KiB
JavaScript
370 行
10 KiB
JavaScript
// I will rewrite it but I'm too lazy to
|
|
const fs = require('fs');
|
|
const http = require('http');
|
|
|
|
// std::string
|
|
let GNAAHeaderTemplate = fs.readFileSync('header.html', 'utf8');
|
|
const GNAAFooter = fs.readFileSync('footer.html', 'utf8');
|
|
|
|
// std::unordered_map<std::string,std::string>
|
|
const HTMLType = { 'Content-Type': 'text/html;charset=UTF-8' };
|
|
|
|
// Memoization, but I'm not sure if this works properly in JS
|
|
// std::vector<std::string> <- but the string is also used as a binary cache
|
|
let Contents = [];
|
|
|
|
// std::function<std::string(std::string)>
|
|
function ReadAsset(FileName) {
|
|
if (!Contents[FileName])
|
|
Contents[FileName] = fs.readFileSync(FileName);
|
|
return Contents[FileName];
|
|
}
|
|
|
|
// std::vector<bool>
|
|
let Dasein = [];
|
|
|
|
// std::function<std::future<bool>(std::string)>
|
|
async function FileExistence(FileName) {
|
|
if (!Dasein[FileName])
|
|
Dasein[FileName] =
|
|
await fs.promises
|
|
.access(FileName)
|
|
.then(() => true,
|
|
() => false);
|
|
return Dasein[FileName];
|
|
}
|
|
|
|
/*
|
|
* struct Page {
|
|
* std::string href, Name;
|
|
* };
|
|
* std::vector<Page>
|
|
*/
|
|
const Pages = [
|
|
{href: "/", Name: "Home"},
|
|
{href: "/corporate", Name: "Corporate"},
|
|
{href: "/products", Name: "Products"},
|
|
{href: "/support", Name: "Support"},
|
|
{href: "/testimonials", Name: "Testimonials"},
|
|
{href: "/faq", Name: "FAQ"},
|
|
{href: "/contact", Name: "Contact"},
|
|
{href: "/join", Name: "Join"},
|
|
{href: "/members", Name: "Members"},
|
|
{href: "/gayniggers/from/outer/space", Name: "Movie"},
|
|
];
|
|
|
|
// req: http.ClientRequest
|
|
// res: http.ServerResponse
|
|
async function GNAAServer(req, res) {
|
|
try {
|
|
res.setHeader("Cache-Control","max-age=148869");
|
|
res.setHeader("Pragma","max-age=148869"); // For dinosaur browsers
|
|
res.setHeader("Connection","close");
|
|
res.removeHeader("Timeout");
|
|
const GenerateHeader = () => {
|
|
let ret = `<ul class="neat">`;
|
|
Pages.forEach((x) => {
|
|
ret += '<li><a '
|
|
+ (req.url === x.href ? 'class="active"' : "")
|
|
+ ' href="'
|
|
+ x.href
|
|
+ '">'
|
|
+ x.Name
|
|
+ '</a></li>';
|
|
});
|
|
return ret + '</ul></div>'
|
|
};
|
|
const GNAAHeader = GNAAHeaderTemplate + GenerateHeader();
|
|
console.log(
|
|
new Date().toLocaleString(),
|
|
req.headers.host,
|
|
req.url,
|
|
'"' + req.headers['user-agent'] + '"'
|
|
);
|
|
// std::string
|
|
let Request = '';
|
|
// bool
|
|
let finished = false;
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
|
// std::vector<std::unordered_map<std::string,std::string>>
|
|
const MimeTypes = {
|
|
css: 'text/css',
|
|
png: 'image/png',
|
|
jpg: 'image/jpg',
|
|
gif: 'image/gif',
|
|
mp4: 'video/mp4',
|
|
wav: 'audio/wav',
|
|
ico: 'image/vnd.microsoft.icon',
|
|
svg: 'image/svg+xml',
|
|
}
|
|
|
|
const NotFound = () => {
|
|
res.writeHead(404, HTMLType);
|
|
Request += GNAAHeader;
|
|
Request += `
|
|
<div class="content neat">
|
|
<h1>Not Found</h1>
|
|
The page you were looking for "<i>`
|
|
Request += req.url;
|
|
Request += `</i>" was not found on this site.</div>
|
|
</div>`;
|
|
Request += GNAAFooter;
|
|
res.end(Request)
|
|
};
|
|
// std::vector<std::string>
|
|
const StaticPages = [
|
|
'',
|
|
'corporate',
|
|
'products',
|
|
'support',
|
|
'testimonials',
|
|
'faq',
|
|
'join',
|
|
//'members',
|
|
]
|
|
|
|
if (StaticPages.includes(req.url.slice(1))) {
|
|
res.writeHead(200, HTMLType);
|
|
Request += GNAAHeader;
|
|
Request += ReadAsset('.' + (req.url === '/' ? '/index'
|
|
: req.url)
|
|
+ '.html');
|
|
res.end(Request + GNAAFooter);
|
|
} else if (req.url === "/members") {
|
|
res.writeHead(200,HTMLType);
|
|
res.end(ReadAsset("./members.html"));
|
|
} else if (req.url === "/gayniggers/from/outer/space") {
|
|
res.writeHead(200, HTMLType);
|
|
res.end(`<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>GayNiggers From Outer Space</title>
|
|
<meta name="description" content="Watch GayNiggers From Outer Space, digitally remasterd, with subtitles for the aurally impared. Blind need not apply. All content is owned by the respective creator. Site courtesy of GNAA.">
|
|
<meta name="keywords" content="Gay, Niggers, gayniggers, from, outer, space, outerspace, gnaa, gay nigger, gay niggers, gaynigger, gay nigger association of america">
|
|
<meta name="robots" content="index, follow">
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
body {
|
|
overflow: hidden;
|
|
background-color: black;
|
|
}
|
|
video {
|
|
height: 100vh;
|
|
width: 100%;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<video controls autoplay>
|
|
<source src="/gayniggers/from/outer/space/gay.mp4" type="video/mp4">
|
|
<track label="English" kind="subtitles" srclang="en" src="/gay.vtt">
|
|
</video>
|
|
</body>
|
|
</html>
|
|
|
|
`)
|
|
} else if (req.url.startsWith('/assets') ||
|
|
req.url.startsWith('/lastmeasure') ||
|
|
req.url === "/gayniggers/from/outer/space/gay.mp4" ||
|
|
req.url === '/favicon.ico') {
|
|
const FilePath = '.' + req.url;
|
|
const FileExists = await FileExistence(FilePath);
|
|
if (FileExists) {
|
|
const FileExt = require('path')
|
|
.extname(FilePath)
|
|
.slice(1)
|
|
.toLowerCase();
|
|
res.writeHead(200, { 'Content-Type': MimeTypes[FileExt] })
|
|
res.end(ReadAsset(FilePath));
|
|
} else NotFound();
|
|
} else if (req.url === '/contact') {
|
|
res.writeHead(200, HTMLType)
|
|
Request += GNAAHeader
|
|
Request += `
|
|
<div class="content neat">
|
|
<h1>Contact</h1>
|
|
<table class="gallery">
|
|
<tr>
|
|
<td>
|
|
<img class="thumb" src="/assets/pictures/contact.jpg" /> </td>
|
|
<td>
|
|
<b>Contact GNAA</b><br>
|
|
Please submit your comments and queries via our friendly feedback form. All submissions are reviewed. If we feel the matter warrants our attention and you leave details, a GNAA representative will get in touch with you shortly. Maybe.<br>
|
|
The contact form can also be used to place orders. Please see <a href="/products">our "products" page</a> for more details.<br>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<br><br>
|
|
<form method="POST" action="">
|
|
<table class="form">
|
|
<tr>
|
|
<td>
|
|
</td>
|
|
<td>`
|
|
if (req.method === 'POST') {
|
|
const stream = fs.createWriteStream('gayniggers.txt', { flags: 'a' });
|
|
let body = ''
|
|
req.on('data', chunk => {
|
|
body += chunk
|
|
if (body.length > 1e6) // spam detection
|
|
req.connection.destroy();
|
|
})
|
|
let ParsedBody = {}
|
|
let ParsedText = {}
|
|
req.on('end', () => {
|
|
ParsedBody = require('querystring').parse(body)
|
|
ParsedText = JSON.stringify(ParsedBody) + '\n'
|
|
stream.write(ParsedText)
|
|
console.log(ParsedText)
|
|
// std::vector<std::string>
|
|
const Fields = [
|
|
'Name',
|
|
'Subject',
|
|
'E-mail',
|
|
'Message',
|
|
]
|
|
let /*bool*/ empty = false
|
|
// std::vector<std::string>
|
|
let EmptyFields = [];
|
|
[...Fields.slice(0,3),"content"].forEach((x) => {
|
|
let str = Array
|
|
.prototype
|
|
.filter
|
|
.call(x.toLowerCase(), y => {
|
|
return y !== '-';
|
|
})
|
|
.join('')
|
|
if (!ParsedBody[str]) {
|
|
empty = true
|
|
EmptyFields.push(x)
|
|
} //else console.log(ParsedBody[str]);
|
|
})
|
|
/*
|
|
* struct Tag {
|
|
* std::string Placeholder, Name, Value;
|
|
* };
|
|
* std::vector<Tag> InputFields;
|
|
*/
|
|
let InputFields = [];
|
|
Fields.slice(0, 3).forEach((i) => {
|
|
let Name = Array.prototype
|
|
.filter
|
|
.call(
|
|
i.toLowerCase(),
|
|
(x) => {
|
|
return x !== '-';
|
|
})
|
|
.join('');
|
|
InputFields.push({
|
|
Placeholder: i,
|
|
Name: Name,
|
|
Value: ParsedBody[Name] ? ParsedBody[Name]
|
|
: "",
|
|
})
|
|
})
|
|
if (empty) {
|
|
Request += `<span class="bad">You cannot leave the `
|
|
Request += EmptyFields[0]
|
|
Request += ` blank.</span>`
|
|
} else {
|
|
Request += `<span class="good">Thank you for contacting us!</span>`
|
|
InputFields.forEach((x) => { x.Value = "" });
|
|
ParsedBody['content'] = "";
|
|
}
|
|
Request += '</td></tr>'
|
|
InputFields.forEach(x => {
|
|
Request += `<tr><td>`
|
|
Request += x.Placeholder
|
|
Request += '</td><td>'
|
|
Request += '<input type="text" placeholder="'
|
|
Request += x.Placeholder
|
|
Request += '" name="'
|
|
Request += x.Name;
|
|
Request += '" value="'
|
|
Request += x.Value ? x.Value : ''
|
|
Request += '"><br>'
|
|
Request += `</td></tr>`
|
|
})
|
|
Request += `<tr><td>Message</td><td><textarea placeholder="Message" name="content">`
|
|
Request += ParsedBody['content'] ? ParsedBody['content']
|
|
: "";
|
|
Request += `</textarea><br></td></tr>`
|
|
Request += `<tr>
|
|
<td>
|
|
</td>
|
|
<td>
|
|
<input type="submit" value="Submit" name="submit" />
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</form>
|
|
<br><br>
|
|
</div>
|
|
</div>
|
|
`
|
|
res.end(Request + GNAAFooter);
|
|
});
|
|
} else/*GET*/ {
|
|
Request += `</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
Name
|
|
</td>
|
|
<td>
|
|
<input type="text" placeholder="Name" name="name" value=""><br>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
Subject
|
|
</td>
|
|
<td>
|
|
<input type="text" placeholder="Subject" name="subject" value=""><br>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
E-mail
|
|
</td>
|
|
<td>
|
|
<input type="text" placeholder="E-mail" name="email" value=""><br>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
Message
|
|
</td>
|
|
<td>
|
|
<textarea placeholder="Message" name="content"></textarea><br>
|
|
</td>
|
|
</tr>`;
|
|
Request += `<tr>
|
|
<td>
|
|
</td>
|
|
<td>
|
|
<input type="submit" value="Submit" name="submit" />
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</form>
|
|
<br><br>
|
|
</div>
|
|
</div>`;
|
|
res.end(Request + GNAAFooter);
|
|
}
|
|
} else NotFound();
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
res.writeHead(500);
|
|
res.end('Something went wrong idk kek, try again nigger');
|
|
}
|
|
}
|
|
|
|
http.createServer(GNAAServer)
|
|
.listen(1488/*, 127.0.0.1"*/);
|