From ad36e794a8fe23a069d23dbdec8daa191f25bcb8 Mon Sep 17 00:00:00 2001 From: Wessel Damian Tip Date: Wed, 16 Jan 2019 17:06:03 +0100 Subject: [PATCH] Upload main code --- .gitignore | 1 + README.md | 49 ++++++++++++++++++++++++++++ extensions/mimes.json | 1 + extensions/static.js | 47 +++++++++++++++++++++++++++ index.js | 4 +++ media/kirb.gif | Bin 0 -> 63936 bytes model/KirbeRequest.js | 16 ++++++++++ model/KirbeResponse.js | 50 +++++++++++++++++++++++++++++ model/KirbeServer.js | 71 +++++++++++++++++++++++++++++++++++++++++ package.json | 34 ++++++++++++++++++++ test.js | 28 ++++++++++++++++ 11 files changed, 301 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 extensions/mimes.json create mode 100644 extensions/static.js create mode 100644 index.js create mode 100644 media/kirb.gif create mode 100644 model/KirbeRequest.js create mode 100644 model/KirbeResponse.js create mode 100644 model/KirbeServer.js create mode 100644 package.json create mode 100644 test.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..464ec01 --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# ![Icon](media/kirb.gif "Dancing krib") Kirbe + +> A lightweight and fast Node.js HTTP server library + +> [GitHub](https://www.github.com/PassTheWessel/Kirbe) **|** [NPM](https://www.npmjs.com/package/kirbe) + +## Installing +```sh +$ yarn add kirbe # Install w/ Yarn (the superior package manager) +$ npm i kirbe # Install w/ NPM +``` + +## Usage +#### Start a HTTP(s) server on port 8080 and add some routes +```js +const kirbe = require( 'kirbe' ); // Define kirbe +const app = new kirbe(); // Make your kirbe client + +app.route( '/bear', 'GET' ( req, res ) => res.status( 200 ).body({ 'bear': 'cop' }) ); +app.route( ( req, res ) => res.status( 404 ).body( 'Error: Content not found!' ).end() ); +app.get( '/kirb', ( req, res ) => { + res.writeHead( 201, { 'test': 'hi' }); + res.end({ 'key': 'hi' }); +}); + +// HTTP +app.listen( 8080, () => console.log( 'Listening on port 8080!' ) ); +// HTTPS +const https = require( 'https' ); // This should be at the top of your code +https.createServer( app.externalHandler ).listen( 8080 ); +``` + +## Default extensions ( [/extensions](extensions) ) +#### Static +> Host static files on your website + +##### Usage +```js +const path = require( 'path' ); // Define path +const kirbe = require( 'kirbe' ); // Define kirbe +const app = new kirbe(); // Make your kirbe client + +app.use( kirbe.static( path.join( __dirname, 'static' ) ) ); +``` + +### Why use kirbe? +Kirbe is a lightweight and fast HTTP server library, especially comparing to express which is around 1mb. If you want any featuers that aren't inside of Kirbe yet, you can open an issue or pull request. + +You can join [https://discord.gg/SV7DAE9](https://discord.gg/SV7DAE9) if you need any support using kirbe! \ No newline at end of file diff --git a/extensions/mimes.json b/extensions/mimes.json new file mode 100644 index 0000000..db30936 --- /dev/null +++ b/extensions/mimes.json @@ -0,0 +1 @@ +{".ez":"application/andrew-inset",".aw":"application/applixware",".atom":"application/atom+xml",".atomcat":"application/atomcat+xml",".atomsvc":"application/atomsvc+xml",".bdoc":"application/bdoc",".ccxml":"application/ccxml+xml",".cdmia":"application/cdmi-capability",".cdmic":"application/cdmi-container",".cdmid":"application/cdmi-domain",".cdmio":"application/cdmi-object",".cdmiq":"application/cdmi-queue",".cu":"application/cu-seeme",".mpd":"application/dash+xml",".davmount":"application/davmount+xml",".dbk":"application/docbook+xml",".dssc":"application/dssc+der",".xdssc":"application/dssc+xml",".ecma":"application/ecmascript",".emma":"application/emma+xml",".epub":"application/epub+zip",".exi":"application/exi",".pfr":"application/font-tdpfr",".woff":"application/font-woff",".woff2":"application/font-woff2",".geojson":"application/geo+json",".gml":"application/gml+xml",".gpx":"application/gpx+xml",".gxf":"application/gxf",".gz":"application/gzip",".stk":"application/hyperstudio",".ink":"application/inkml+xml",".inkml":"application/inkml+xml",".ipfix":"application/ipfix",".jar":"application/java-archive",".war":"application/java-archive",".ear":"application/java-archive",".ser":"application/java-serialized-object",".class":"application/java-vm",".js":"application/javascript",".mjs":"application/javascript",".json":"application/json",".map":"application/json",".json5":"application/json5",".jsonml":"application/jsonml+json",".jsonld":"application/ld+json",".lostxml":"application/lost+xml",".hqx":"application/mac-binhex40",".cpt":"application/mac-compactpro",".mads":"application/mads+xml",".webmanifest":"application/manifest+json",".mrc":"application/marc",".mrcx":"application/marcxml+xml",".ma":"application/mathematica",".nb":"application/mathematica",".mb":"application/mathematica",".mathml":"application/mathml+xml",".mbox":"application/mbox",".mscml":"application/mediaservercontrol+xml",".metalink":"application/metalink+xml",".meta4":"application/metalink4+xml",".mets":"application/mets+xml",".mods":"application/mods+xml",".m21":"application/mp21",".mp21":"application/mp21",".mp4s":"application/mp4",".m4p":"application/mp4",".doc":"application/msword",".dot":"application/msword",".mxf":"application/mxf",".bin":"application/octet-stream",".dms":"application/octet-stream",".lrf":"application/octet-stream",".mar":"application/octet-stream",".so":"application/octet-stream",".dist":"application/octet-stream",".distz":"application/octet-stream",".pkg":"application/octet-stream",".bpk":"application/octet-stream",".dump":"application/octet-stream",".elc":"application/octet-stream",".deploy":"application/octet-stream",".exe":"application/octet-stream",".dll":"application/octet-stream",".deb":"application/octet-stream",".dmg":"application/octet-stream",".iso":"application/octet-stream",".img":"application/octet-stream",".msi":"application/octet-stream",".msp":"application/octet-stream",".msm":"application/octet-stream",".buffer":"application/octet-stream",".oda":"application/oda",".opf":"application/oebps-package+xml",".ogx":"application/ogg",".omdoc":"application/omdoc+xml",".onetoc":"application/onenote",".onetoc2":"application/onenote",".onetmp":"application/onenote",".onepkg":"application/onenote",".oxps":"application/oxps",".xer":"application/patch-ops-error+xml",".pdf":"application/pdf",".pgp":"application/pgp-encrypted",".asc":"application/pgp-signature",".sig":"application/pgp-signature",".prf":"application/pics-rules",".p10":"application/pkcs10",".p7m":"application/pkcs7-mime",".p7c":"application/pkcs7-mime",".p7s":"application/pkcs7-signature",".p8":"application/pkcs8",".ac":"application/pkix-attr-cert",".cer":"application/pkix-cert",".crl":"application/pkix-crl",".pkipath":"application/pkix-pkipath",".pki":"application/pkixcmp",".pls":"application/pls+xml",".ai":"application/postscript",".eps":"application/postscript",".ps":"application/postscript",".pskcxml":"application/pskc+xml",".rdf":"application/rdf+xml",".rif":"application/reginfo+xml",".rnc":"application/relax-ng-compact-syntax",".rl":"application/resource-lists+xml",".rld":"application/resource-lists-diff+xml",".rs":"application/rls-services+xml",".gbr":"application/rpki-ghostbusters",".mft":"application/rpki-manifest",".roa":"application/rpki-roa",".rsd":"application/rsd+xml",".rss":"application/rss+xml",".rtf":"application/rtf",".sbml":"application/sbml+xml",".scq":"application/scvp-cv-request",".scs":"application/scvp-cv-response",".spq":"application/scvp-vp-request",".spp":"application/scvp-vp-response",".sdp":"application/sdp",".setpay":"application/set-payment-initiation",".setreg":"application/set-registration-initiation",".shf":"application/shf+xml",".smi":"application/smil+xml",".smil":"application/smil+xml",".rq":"application/sparql-query",".srx":"application/sparql-results+xml",".gram":"application/srgs",".grxml":"application/srgs+xml",".sru":"application/sru+xml",".ssdl":"application/ssdl+xml",".ssml":"application/ssml+xml",".tei":"application/tei+xml",".teicorpus":"application/tei+xml",".tfi":"application/thraud+xml",".tsd":"application/timestamped-data",".vxml":"application/voicexml+xml",".wgt":"application/widget",".hlp":"application/winhlp",".wsdl":"application/wsdl+xml",".wspolicy":"application/wspolicy+xml",".xaml":"application/xaml+xml",".xdf":"application/xcap-diff+xml",".xenc":"application/xenc+xml",".xhtml":"application/xhtml+xml",".xht":"application/xhtml+xml",".xml":"application/xml",".xsl":"application/xml",".xsd":"application/xml",".rng":"application/xml",".dtd":"application/xml-dtd",".xop":"application/xop+xml",".xpl":"application/xproc+xml",".xslt":"application/xslt+xml",".xspf":"application/xspf+xml",".mxml":"application/xv+xml",".xhvml":"application/xv+xml",".xvml":"application/xv+xml",".xvm":"application/xv+xml",".yang":"application/yang",".yin":"application/yin+xml",".zip":"application/zip",".adp":"audio/adpcm",".au":"audio/basic",".snd":"audio/basic",".mid":"audio/midi",".midi":"audio/midi",".kar":"audio/midi",".rmi":"audio/midi",".m4a":"audio/mp4",".mp4a":"audio/mp4",".mpga":"audio/mpeg",".mp2":"audio/mpeg",".mp2a":"audio/mpeg",".mp3":"audio/mpeg",".m2a":"audio/mpeg",".m3a":"audio/mpeg",".oga":"audio/ogg",".ogg":"audio/ogg",".spx":"audio/ogg",".s3m":"audio/s3m",".sil":"audio/silk",".wav":"audio/wav",".weba":"audio/webm",".xm":"audio/xm",".otf":"font/otf",".apng":"image/apng",".bmp":"image/bmp",".cgm":"image/cgm",".g3":"image/g3fax",".gif":"image/gif",".ief":"image/ief",".jpeg":"image/jpeg",".jpg":"image/jpeg",".jpe":"image/jpeg",".ktx":"image/ktx",".png":"image/png",".sgi":"image/sgi",".svg":"image/svg+xml",".svgz":"image/svg+xml",".tiff":"image/tiff",".tif":"image/tiff",".webp":"image/webp",".eml":"message/rfc822",".mime":"message/rfc822",".gltf":"model/gltf+json",".glb":"model/gltf-binary",".igs":"model/iges",".iges":"model/iges",".msh":"model/mesh",".mesh":"model/mesh",".silo":"model/mesh",".wrl":"model/vrml",".vrml":"model/vrml",".x3db":"model/x3d+binary",".x3dbz":"model/x3d+binary",".x3dv":"model/x3d+vrml",".x3dvz":"model/x3d+vrml",".x3d":"model/x3d+xml",".x3dz":"model/x3d+xml",".appcache":"text/cache-manifest",".manifest":"text/cache-manifest",".ics":"text/calendar",".ifb":"text/calendar",".coffee":"text/coffeescript",".litcoffee":"text/coffeescript",".css":"text/css",".csv":"text/csv",".hjson":"text/hjson",".html":"text/html",".htm":"text/html",".shtml":"text/html",".jade":"text/jade",".jsx":"text/jsx",".less":"text/less",".markdown":"text/markdown",".md":"text/markdown",".mml":"text/mathml",".n3":"text/n3",".txt":"text/plain",".text":"text/plain",".conf":"text/plain",".def":"text/plain",".list":"text/plain",".log":"text/plain",".in":"text/plain",".ini":"text/plain",".rtx":"text/richtext",".sgml":"text/sgml",".sgm":"text/sgml",".slim":"text/slim",".slm":"text/slim",".stylus":"text/stylus",".styl":"text/stylus",".tsv":"text/tab-separated-values",".t":"text/troff",".tr":"text/troff",".roff":"text/troff",".man":"text/troff",".me":"text/troff",".ms":"text/troff",".ttl":"text/turtle",".uri":"text/uri-list",".uris":"text/uri-list",".urls":"text/uri-list",".vcard":"text/vcard",".vtt":"text/vtt",".yaml":"text/yaml",".yml":"text/yaml",".3gp":"video/3gpp",".3gpp":"video/3gpp",".3g2":"video/3gpp2",".h261":"video/h261",".h263":"video/h263",".h264":"video/h264",".jpgv":"video/jpeg",".jpm":"video/jpm",".jpgm":"video/jpm",".mj2":"video/mj2",".mjp2":"video/mj2",".ts":"video/mp2t",".mp4":"video/mp4",".mp4v":"video/mp4",".mpg4":"video/mp4",".mpeg":"video/mpeg",".mpg":"video/mpeg",".mpe":"video/mpeg",".m1v":"video/mpeg",".m2v":"video/mpeg",".ogv":"video/ogg",".qt":"video/quicktime",".mov":"video/quicktime",".webm":"video/webm"} \ No newline at end of file diff --git a/extensions/static.js b/extensions/static.js new file mode 100644 index 0000000..befe2c6 --- /dev/null +++ b/extensions/static.js @@ -0,0 +1,47 @@ +const fs = require( 'fs' ); +const url = require( 'url' ); +const { join, extname } = require( 'path' ); + +const mimes = JSON.parse( fs.readFileSync( join( __dirname, 'mimes.json' ) ) ); + +module.exports = ( baseDir, indexFile ) => { + if (!baseDir) throw new Error('The argument "baseDir" is required for the extension "kirbe:static"'); + + indexFile = typeof indexFile === 'string' ? indexFile : 'index.html' + return( req, res, next ) => { + if( req.method !== 'GET' ) { next(); return; } + + let requestedPath = req.parsedUrl.pathname.replace( /\/.\.\//g, '' ); + let requestedExt = extname( requestedPath ); + + const filePath = join( baseDir, requestedPath ); + + fs.stat( filePath, ( err, stats ) => { + if( err ) { next(); return; } + + if( stats.isFile() ) { + stats.mtime.setMilliseconds( 0 ); + if ( stats.mtime <= new Date( req.headers[ 'if-modified-since' ] ) ) res.status( 304 ).end(); + else fs.createReadStream( filePath ).pipe( res.status( 200 ).coreRes ); + } else { + if ( req.parsedUrl.pathname.charAt( req.parsedUrl.pathname.length -1 ) !== '/' ) { + res.status(302).header({ 'Location': `${req.parsedUrl.pathname}/` }).end(); + return; + } + + requestedPath = join( filePath, indexFile ); + requestedExt = extname( requestedPath ); + + fs.readFile( requestedPath, ( err, data ) => { + if (err) next(); + else { + res.body( data ).status(200).header({ + 'Content-Type': ( mimes.hasOwnProperty( requestedExt ) ? mimes[ requestedExt ] : 'application/octet-stream' ), + 'Last-Modified': stats.mtime.toString() + }).end(); + } + }); + } + }); + }; +}; \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..dda2926 --- /dev/null +++ b/index.js @@ -0,0 +1,4 @@ +const kirbe = exports; + +module.exports = require( './model/KirbeServer' ); +kirbe.static = require( './extensions/static' ); \ No newline at end of file diff --git a/media/kirb.gif b/media/kirb.gif new file mode 100644 index 0000000000000000000000000000000000000000..18b2a2a51c7a3c8a9075ec06af67ff63fb81cea1 GIT binary patch literal 63936 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 this.headers[ v.toLowerCase() ] = a[ v ] ); + else this.headers[ a.toLowerCase() ] = b; + + return this; + } + + status( code, message ) { + this.statusCode = code; + this.statusMessage = message; + + return this; + } + + writeHead( status, headers ) { + if ( status ) this.status( status ); + if ( headers ) this.header( headers ); + } + + end( data ) { + if ( data ) this.body( data ); + + if (this.statusMessage) this.coreRes.writeHead( this.statusCode, this.statusMessage, this.headers ); + else this.coreRes.writeHead( this.statusCode, this.headers ); + this.coreRes.end( this.data ); + + return this; + } +}; \ No newline at end of file diff --git a/model/KirbeServer.js b/model/KirbeServer.js new file mode 100644 index 0000000..d143ae8 --- /dev/null +++ b/model/KirbeServer.js @@ -0,0 +1,71 @@ +const { join } = require( 'path' ); +const { createServer } = require( 'http' ); + +const KirbeRequest = require( join( __dirname, 'KirbeRequest.js' ) ); +const KirbeResponse = require( join( __dirname, 'KirbeResponse.js' ) ); + +const methods = [ 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH' ]; +const isUrl = ( c ) => (typeof c === 'string' && !methods.includes( c ) ) || c instanceof RegExp; + +module.exports = class KirbeServer { + constructor() { + this.internalServer = createServer( ( req, res ) => this.handler.apply( this, [ req, res ] ) ); + this.externalHandler = ( req, res ) => this.handler( req, res ); + + this.routes = []; + this.extensions = []; + + methods.forEach( ( v ) => this[ v.toLowerCase() ] = ( a, b ) => this.route( v, a, b ) ); + } + + use( extension ) { this.extensions.push( extension ); } + + route( a, b, c ) { + this.routes.push({ + 'target': { + 'path' : isUrl( a ) ? a : ( isUrl( b ) ? b : null ), + 'method': methods.includes( a ) ? a : null + }, + 'handler': c || b || a + }); + } + + handler( req, res ) { + let body = Buffer.alloc( 0 ); + + req.on( 'data', ( c ) => body = Buffer.concat([ body, c ]) ); + req.on( 'end', () => { + const request = new KirbeRequest( req, body ); + const response = new KirbeResponse( res ); + + const start = () => { + for( let i = 0; i < this.routes.length; i++ ) { + const current = this.routes[ i ]; + + if ( current.target.method && request.method !== current.target.method ) continue; + if ( current.target.path ) { + if ( current.target.path instanceof RegExp && !request.parsedUrl.pathname.match( current.target.path ) ) continue; + else if ( current.target.path !== request.parsedUrl.pathname ) continue; + } + + current.handler( request, response ); + break; + } + }; + + let currentExt = 0; + const nextExt = () => { + if ( this.extensions.length >= currentExt + 1 ) { + currentExt++; + this.extensions[ currentExt -1 ]( request, response, nextExt ); + } else start(); + }; + + nextExt(); + }); + } + + listen( a, b, c ) { + this.internalServer.listen( typeof a === 'number' ? a : 80, typeof b === 'string' ? b : null, typeof b === 'function' ? b : null ); + } +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..0615e60 --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "kirbe", + "version": "0.0.1", + "description": "👻 A powerful and lightweight Node.js HTTP server library", + "main": "index.js", + "author": "Wessel \"wesselgame\" T ", + "license": "MIT", + "private": false, + "files": [ + "index.js", + "model", + "LICENSE" + ], + "bugs": { + "url": "https://www.github.com/PassTheWessel/kirbe/issues" + }, + "homepage": "https://www.github.com/PassTheWessel/kirbe#readme", + "repository": { + "type": "git", + "url": "https://www.github.com/PassTheWessel/kirbe" + }, + "keywords": [ + "framework", + "fast", + "web", + "rest", + "restful", + "router", + "app", + "api", + "lightweight" + ], + "devDependencies": { "wumpfetch": "^0.0.4" } +} diff --git a/test.js b/test.js new file mode 100644 index 0000000..f1e7750 --- /dev/null +++ b/test.js @@ -0,0 +1,28 @@ +const w = require( 'wumpfetch' ); +const Kirbe = require( './index' ); + +const app = new Kirbe(); + +app.use( ( req, res, next ) => req.url === '/testExtension' ? res.status( 200 ).end() : next() ); + +app.post( '/parse', ( req, res ) => res.body({ 'sent': req.json() }).end() ); +app.route( 'GET', '/statusMsg', ( req, res ) => res.status( 200, 'kirbe won' ).end() ); +app.route( 'POST', ( req, res ) => res.body( 'Gotta catch em all!' ).end() ); +app.route( '/compatibility', ( req, res ) => { + res.writeHead( 201, { 'test': 'hi' }); + res.end({ 'key': 'hi' }); +}); +app.route( ( req, res ) => res.status( 404 ).body( 'Error: Content not found!' ).end() ); + +;( async() => { + const res = []; + res.push( await w( 'http://127.0.0.1:4040/bear' ).send() ); + res.push( await w( 'http://127.0.0.1:4040/statusMsg' ).send() ); + res.push( await w( 'http://127.0.0.1:4040/compatibility' ).send() ); + res.push( await w( 'http://127.0.0.1:4040/testExtension' ).send() ); + res.push( await w( 'http://127.0.0.1:4040/parse', 'POST' ).body({ 'hello': 123 }).send() ); + + res.forEach( ( v, i ) => console.log( `${i}: ${v.statusCode}` ) ); +})(); + +app.listen( 4040, '127.0.0.1' ); \ No newline at end of file