Created
December 16, 2018 08:29
-
-
Save kyle-rb/9a6d54a26ca07d32f8f9be22e7e807a0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const http = require('http'); | |
const https = require('https'); | |
const URL = require('url').URL; | |
const fs = require('fs'); | |
const badRequestResponse = '<html><head><title>400 Bad Request</title><body><h1>400 Bad Request</h1><h2>Required URL parameters are missing</h2></body></html>'; | |
const notFoundResponse = '<html><head><title>404 Not Found</title><body><h1>404 Not Found</h1><h2>The requested page was not found on the server</h2></body></html>'; | |
const MIME_TYPES = { | |
'mp4': 'video/mp4', 'm4v':'video/mp4', 'webm': 'video/webm', 'mkv': 'video/x-matroska', | |
'png': 'image/png', 'jpg':'image/jpeg', 'jpeg': 'image/jpeg', 'gif': 'image/gif', | |
'ico': 'image/x-icon', 'svg':'image/svg+xml', 'webp': 'image/webp', | |
'mp3': 'audio/mpeg', 'wav':'audio/wav', | |
'txt': 'text/plain', 'html':'text/html', 'css': 'text/css', 'js': 'text/javascript', | |
'xml': 'text/xml' // possibly supposed to be application/xml, but it's debatable | |
}; // all the filetypes that might need to be served, I guess | |
const server = http.createServer(function(request, response) { | |
if (request.url === '/') { // if request is for the root | |
request.url += 'index.html'; | |
} | |
let url = new URL('http://localhost:8000' + request.url); // need domain in url for constructor | |
if (url.pathname === '/req/') { | |
if (url.searchParams.get('url')) { | |
makeRequestAndRespond(decodeURIComponent(url.searchParams.get('url')), response); | |
} | |
else { | |
response.writeHead(400, { 'Content-Type': MIME_TYPES.html }); // 400 bad request | |
response.end(badRequestResponse); | |
} | |
} | |
else { // otherwise this is a regular static file request | |
let fileExtension = url.pathname.split('.').pop(); | |
let mimeType = MIME_TYPES[fileExtension] || 'application/octet-stream'; | |
let fileSystemPath = '.' + url.pathname; | |
fs.lstat(fileSystemPath, function(err, stats) { // make sure file exists | |
if (err || stats.isDirectory()) { | |
response.writeHead(404, { 'Content-Type': MIME_TYPES.html }); // 404 not found | |
response.end(notFoundResponse); | |
return; | |
} | |
response.writeHead(200, { 'Content-Type': mimeType }); | |
let fileStream = fs.createReadStream(fileSystemPath) | |
.on('open', function() { | |
fileStream.pipe(response); | |
}) | |
.on('error', function(err) { | |
console.log(err); | |
response.end(err); | |
}); | |
}); | |
} | |
}); | |
server.listen(8000, '0.0.0.0', function() { | |
console.log('server running at http://0.0.0.0:8000'); | |
}); | |
/* | |
* Make a request to a remote page and pass that remote response through to the local response that | |
* was passed in to the function. | |
*/ | |
function makeRequestAndRespond(urlString, localResponse) { | |
let url; | |
try { | |
url = new URL(urlString); | |
} | |
catch (e) { // if the URL is invalid, 400 response | |
response.writeHead(400, { 'Content-Type': MIME_TYPES.html }); // 400 bad request | |
response.end(badRequestResponse); | |
return; | |
} | |
let requestModule = http; | |
if (url.protocol === 'https:') { // secure requests require using https module | |
requestModule = https; | |
} | |
let requestOptions = { | |
protocol: url.protocol, | |
hostname: url.hostname, | |
port: url.port, | |
path: url.pathname + url.search, | |
headers: { referer: urlString } | |
}; | |
return requestModule.get(requestOptions, function(remoteResponse) { | |
var body = ''; | |
remoteResponse.on('data', function(d) { | |
body += d; // continuously update stream with data | |
}); | |
remoteResponse.on('end', function() { | |
localResponse.writeHead(remoteResponse.statusCode); | |
localResponse.end(body); | |
}); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment