1
0
Fork 0
forked from svrjs/svrjs

Compare commits

..

2 commits

8 changed files with 143 additions and 10 deletions

View file

@ -81,7 +81,7 @@ After installing the packages, build SVR.JS with this command:
```bash ```bash
npm run build npm run build
``` ```
After running the command, you will get bundled SVR.JS script, around with built-in utilities and assets in the `dist` directory. You will also get a zip archive in `out` directory, that can be installed using SVR.JS installer After running the command, you will get bundled SVR.JS script, around with built-in utilities and assets in the `dist` directory. You will also get a zip archive in `out` directory, that can be installed using SVR.JS installer. Additionally, you will get the SVR.JS Core package contents in the `core` directory, which you can publish by running `npm publish` in the `core` directory.
## Installation (built from source) ## Installation (built from source)
@ -118,6 +118,8 @@ You can read the [SVR.JS documentation](https://svrjs.org/docs) to get informati
The file structure for SVR.JS source code looks like this: The file structure for SVR.JS source code looks like this:
- .husky - Git hooks - .husky - Git hooks
- assets - files to copy into dist folder and to the archive - assets - files to copy into dist folder and to the archive
- core - contains SVR.JS Core
- coreAssets - files to copy into core folder
- dist - contains SVR.JS, assets, and SVR.JS utiltiies - dist - contains SVR.JS, assets, and SVR.JS utiltiies
- generatedAssets - assets generated by the build script - generatedAssets - assets generated by the build script
- out - contains SVR.JS zip archive - out - contains SVR.JS zip archive

View file

@ -1,3 +1,64 @@
# SVR.JS Core # SVR.JS Core
TODO SVR.JS Core is a library for static file serving, built from SVR.JS source code.
Example code (with Node.JS "http" module):
```javascript
var http = require("http");
var fs = require("fs");
var url = require("url");
var svrjsCore = require("svrjs-core").init(); // Initialize SVR.JS Core
var server = http.createServer(function (req,res) {
if(url.parse(req.url).pathname == "/useragent") {
res.writeHead(200, "OK", {"content-type": "text-plain"}); // Output as plain text
res.end("Your user agent: " + req.headers["user-agent"]); // Send user agent
} else {
svrjsCore(req,res); // Serve static content
}
}).listen(8888);
```
Example code (with Express):
```javascript
var express = require("express");
var svrjsCore = require("svrjs-core");
var app = express();
app.use(svrjsCore());
app.listen(3000);
```
## Methods
### *svrjsCore([config])*
Parameters:
- *config* - the SVR.JS Core configuration (optional, *Object*)
Returns: the request handler for use in Node.JS HTTP server or Express, with three parameters (*req*, *res*, and optional *next*)
The *config* object is almost the same format as SVR.JS configuration. You can read about SVR.JS configuration properties in [the SVR.JS documentation](https://svrjs.org/docs/config/configuration).
However, only these SVR.JS configuration properties apply to SVR.JS Core:
- *users*
- *page404*
- *enableCompression*
- *customHeaders*
- *enableDirectoryListing*
- *enableDirectoryListingWithDefaultHead*
- *serverAdministratorEmail*
- *stackHidden*
- *exposeServerVersion*
- *dontCompress*
- *enableIPSpoofing*
- *enableETag*
- *rewriteDirtyURLs*
- *errorPages*
- *disableTrailingSlashRedirects*
- *allowDoubleSlashes*
### *svrjsCore.init([config])*
An alias to the *svrjsCore()* function

View file

@ -11,7 +11,6 @@ const svrjsCoreInfo = JSON.parse(
fs.readFileSync(__dirname + "/svrjs.core.json") fs.readFileSync(__dirname + "/svrjs.core.json")
); );
const { externalPackages } = svrjsCoreInfo; const { externalPackages } = svrjsCoreInfo;
const coreVersion = svrjsCoreInfo.version;
const corePackageJSON = svrjsCoreInfo.packageJSON; const corePackageJSON = svrjsCoreInfo.packageJSON;
const isDev = process.env.NODE_ENV == "development"; const isDev = process.env.NODE_ENV == "development";
@ -265,7 +264,7 @@ if (!isDev) {
const packageJSON = Object.assign({}, corePackageJSON); const packageJSON = Object.assign({}, corePackageJSON);
// Add package.json properties // Add package.json properties
packageJSON.version = coreVersion; packageJSON.version = version;
packageJSON.main = "./svr.core.js"; packageJSON.main = "./svr.core.js";
packageJSON.dependencies = coreDependencyNames.reduce( packageJSON.dependencies = coreDependencyNames.reduce(
(previousDependencies, dependency) => { (previousDependencies, dependency) => {

View file

@ -13,7 +13,6 @@ const statusCodes = require("./res/statusCodes.js");
const middleware = [ const middleware = [
require("./middleware/urlSanitizer.js"), require("./middleware/urlSanitizer.js"),
require("./middleware/rewriteURL.js"),
require("./middleware/redirectTrailingSlashes.js"), require("./middleware/redirectTrailingSlashes.js"),
require("./middleware/defaultHandlerChecks.js"), require("./middleware/defaultHandlerChecks.js"),
require("./middleware/staticFileServingAndDirectoryListings.js") require("./middleware/staticFileServingAndDirectoryListings.js")
@ -591,6 +590,9 @@ function requestHandler(req, res, next) {
? config.domain ? config.domain
: "unknown.invalid") : "unknown.invalid")
); );
// req.originalParsedURL fallback
req.originalParsedURL = req.parsedURL;
} catch (err) { } catch (err) {
res.error(400, err); res.error(400, err);
return; return;
@ -626,6 +628,43 @@ function requestHandler(req, res, next) {
function init(config) { function init(config) {
if (config) coreConfig = config; if (config) coreConfig = config;
if (coreConfig.users === undefined) coreConfig.users = [];
if (coreConfig.page404 === undefined) coreConfig.page404 = "404.html";
if (coreConfig.enableCompression === undefined)
coreConfig.enableCompression = true;
if (coreConfig.customHeaders === undefined) coreConfig.customHeaders = {};
if (coreConfig.enableDirectoryListing === undefined)
coreConfig.enableDirectoryListing = true;
if (coreConfig.enableDirectoryListingWithDefaultHead === undefined)
coreConfig.enableDirectoryListingWithDefaultHead = false;
if (coreConfig.serverAdministratorEmail === undefined)
coreConfig.serverAdministratorEmail = "[no contact information]";
if (coreConfig.stackHidden === undefined) coreConfig.stackHidden = false;
if (coreConfig.exposeServerVersion === undefined)
coreConfig.exposeServerVersion = true;
if (coreConfig.dontCompress === undefined)
coreConfig.dontCompress = [
"/.*\\.ipxe$/",
"/.*\\.(?:jpe?g|png|bmp|tiff|jfif|gif|webp)$/",
"/.*\\.(?:[id]mg|iso|flp)$/",
"/.*\\.(?:zip|rar|bz2|[gb7x]z|lzma|tar)$/",
"/.*\\.(?:mp[34]|mov|wm[av]|avi|webm|og[gv]|mk[va])$/"
];
if (coreConfig.enableIPSpoofing === undefined)
coreConfig.enableIPSpoofing = false;
if (coreConfig.enableETag === undefined) coreConfig.enableETag = true;
if (coreConfig.rewriteDirtyURLs === undefined)
coreConfig.rewriteDirtyURLs = false;
if (coreConfig.errorPages === undefined) coreConfig.errorPages = [];
if (coreConfig.disableTrailingSlashRedirects === undefined)
coreConfig.disableTrailingSlashRedirects = false;
if (coreConfig.allowDoubleSlashes === undefined)
coreConfig.allowDoubleSlashes = false;
// You wouldn't use SVR.JS mods in SVR.JS Core
coreConfig.exposeModsInErrorPages = false;
return requestHandler; return requestHandler;
} }

View file

@ -706,6 +706,9 @@ function requestHandler(req, res) {
? config.domain ? config.domain
: "unknown.invalid") : "unknown.invalid")
); );
// req.originalParsedURL fallback
req.originalParsedURL = req.parsedURL;
} catch (err) { } catch (err) {
res.error(400, err); res.error(400, err);
return; return;

View file

@ -980,7 +980,32 @@ module.exports = (req, res, logFacilities, config, next) => {
} else if (dirImagesMissing) { } else if (dirImagesMissing) {
fs.stat(readFrom, (e, s) => { fs.stat(readFrom, (e, s) => {
if (e || !s.isFile()) { if (e || !s.isFile()) {
properDirectoryListingAndStaticFileServe(); if (err.code == "ENOENT") {
res.error(404);
logFacilities.errmessage("Resource not found.");
return;
} else if (err.code == "ENOTDIR") {
res.error(404); // Assume that file doesn't exist.
logFacilities.errmessage("Resource not found.");
return;
} else if (err.code == "EACCES") {
res.error(403);
logFacilities.errmessage("Access denied.");
return;
} else if (err.code == "ENAMETOOLONG") {
res.error(414);
return;
} else if (err.code == "EMFILE") {
res.error(503);
return;
} else if (err.code == "ELOOP") {
res.error(508); // The symbolic link loop is detected during file system operations.
logFacilities.errmessage("Symbolic link loop detected.");
return;
} else {
res.error(500, err);
return;
}
} else { } else {
stats = s; stats = s;
properDirectoryListingAndStaticFileServe(); properDirectoryListingAndStaticFileServe();

View file

@ -1,5 +1,7 @@
const svrjsInfo = require("../../svrjs.core.json"); const svrjsCoreInfo = require("../../svrjs.core.json");
const { version, name } = svrjsInfo; const { name } = svrjsCoreInfo;
const svrjsInfo = require("../../svrjs.json");
const { version } = svrjsInfo;
const getOS = require("./getOS.js"); const getOS = require("./getOS.js");
function generateServerString(exposeServerVersion) { function generateServerString(exposeServerVersion) {

View file

@ -1,5 +1,4 @@
{ {
"version": "Nightly-GitNext",
"name": "SVR.JS Core", "name": "SVR.JS Core",
"externalPackages": ["mime-types"], "externalPackages": ["mime-types"],
"packageJSON": { "packageJSON": {
@ -18,6 +17,9 @@
"middleware" "middleware"
], ],
"homepage": "https://svrjs.org", "homepage": "https://svrjs.org",
"license": "MIT" "license": "MIT",
"engines": {
"node": ">=10.0.0"
}
} }
} }