| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import http from 'http';
- import path from 'path';
- import { createReadStream, existsSync, statSync } from 'fs';
- const mimeTypes = {
- '.html': 'text/html',
- '.js': 'application/javascript',
- '.css': 'text/css',
- '.json': 'application/json',
- '.png': 'image/png',
- '.jpg': 'image/jpeg',
- '.gif': 'image/gif',
- '.svg': 'image/svg+xml',
- '.mp3': 'audio/mpeg',
- '.mp4': 'video/mp4',
- '.webm': 'video/webm',
- '.ogv': 'video/ogg',
- '.ogg': 'audio/ogg',
- '.woff': 'font/woff',
- '.woff2': 'font/woff2',
- '.ttf': 'font/ttf',
- '.glb': 'model/gltf-binary',
- '.gltf': 'model/gltf+json',
- '.hdr': 'application/octet-stream',
- '.exr': 'application/octet-stream',
- '.fbx': 'application/octet-stream',
- '.bin': 'application/octet-stream',
- '.cube': 'text/plain'
- };
- const rootDirectory = path.resolve();
- const server = http.createServer( ( req, res ) => {
- const pathname = decodeURIComponent( req.url.split( '?' )[ 0 ] );
- const filePath = path.normalize( path.join( rootDirectory, pathname ) );
- // Prevent path traversal attacks
- if ( ! filePath.startsWith( rootDirectory ) ) {
- res.writeHead( 403 );
- res.end( 'Forbidden' );
- return;
- }
- if ( ! existsSync( filePath ) ) {
- res.writeHead( 404 );
- res.end( 'File not found' );
- return;
- }
- const ext = path.extname( filePath ).toLowerCase();
- const contentType = mimeTypes[ ext ] || 'application/octet-stream';
- const stat = statSync( filePath );
- const fileSize = stat.size;
- const range = req.headers.range;
- if ( range ) {
- const parts = range.replace( /bytes=/, '' ).split( '-' );
- const start = parseInt( parts[ 0 ], 10 );
- const end = parts[ 1 ] ? parseInt( parts[ 1 ], 10 ) : fileSize - 1;
- res.writeHead( 206, {
- 'Content-Range': `bytes ${start}-${end}/${fileSize}`,
- 'Accept-Ranges': 'bytes',
- 'Content-Length': end - start + 1,
- 'Content-Type': contentType
- } );
- createReadStream( filePath, { start, end } ).pipe( res );
- } else {
- res.writeHead( 200, {
- 'Content-Length': fileSize,
- 'Content-Type': contentType
- } );
- createReadStream( filePath ).pipe( res );
- }
- } );
- export default server;
|