Neurotic Pumpkin Murderer

    ok-server

    1.0.5 • Public • Published

    ok-server

    ok-server is simple web server implemented with node.js HttpSever. It can be extended by adding it new request handlers for the desired endpoints. It includes two default request handlers, one for the file requests and one for the API requests. It's API request handler is easily extendable. File handler supports partial file requests in addition to normal file transfer.


    Table of contents


    Installation

    npm install ok-server

    Usage

    OKServer object can be initialized with createServer function of ok-server module or instantiating it with new keyword using ok-server property OKServer. Both methods enable extending of the OKServer class. Extending is preferable because it enables the use of event methods of the class.

    Initializing with createSever

    const okserver = require( "ok-server" );
    const server = okserver.createServer({
        logFolder: __dirname + "/log",
        pulseFolder: __dirname,
        optionsFile: __dirname + "/my-server.json"
    });
    

    Extendeding server class

    const okserver = require( "ok-server" );
     
    class MyServer extends okserver.OKServer {
        constructor(options) {
            super(options);
            this.addMimeType({
                ".mp3": "audio/mpeg",
                ".wav": "audio/x-wav"
            });
        }
    }
    

    Initializing with extended server class

    const okserver = require( "ok-server" );
    const server = okserver.createServer({
        serverClass: MyServer,
        logFolder: __dirname + "/log",
        pulseFolder: __dirname,
        optionsFile: __dirname + "/my-server.json"
    });
     
    class MyServer extends okserver.OKServer {
        constructor(options) {
            super(options);
            this.addMimeType({
                ".mp3": "audio/mpeg",
                ".wav": "audio/x-wav"
            });
        }
    }
    

    -- or --

    class MyServer extends require( "ok-server" ).OKServer {
        constructor(options) {
            super(options);
            this.addMimeType({
                ".mp3": "audio/mpeg",
                ".wav": "audio/x-wav"
            });
        }
    }
    
    const server = new MyServer({
        logFolder: __dirname + "/log",
        pulseFolder: __dirname,
        optionsFile: __dirname + "/my-server.json"
    });
    

    Creating initial options file

    Initial options file can be created by executing following source with command line flag /initServerOptions. It will create an option file including default option values. Default option values can also changed as can be seen in the example.

    const okserver = require( "ok-server" );
    const options = okserver.defaultOptions;
    options.port = 3099;
    options.defaultDirectory = "/sites/my-test/site";
    options.mimeTypes[".mp3"] = "audio/mpeg";
    options.mimeTypes[".wav"] = "audio/x-wav";
    okserver.createServer({
        optionsFile: "/sites/my-test/my-server.json"
    });
    


    Request Handlers

    ok-server has two request handlers pre-implemented. Requests on api entry point are handled by the api request handler. File requests on both default directory and all virtual directories are handled by default the default hanlder.

    Implementing and utilizing a new request handler

    Request handlers can be implemented by creating a new request handler javascript module and loading it with server's loadHandler method. The module source must follow a structure similar to the one below. The following three conditions must be met:

    1. New request handler class must extend RequestHandler class defined in requesthandler.js,
    2. The class instances must be given a proper name representing the handler name.
    3. Module must export the new RequestHandler class defined in it.

    The request handler is utilized by defining it as a virtual directory request handler. This is done using the server's addVirtualDirectory method by adding the handler name to the handlerName parameter.

    Request handler prototype

    const RequestHandler = require( "ok-server" ).RequestHandler;
      
    class TestRequestHandler extends RequestHandler {
        constructor (params = {}) {
            params.name = "test"; // handler name
            super(params);
        }
            
        onRequest( context ) {
            const responseHeaders = {};
            let responseBody = "";
            let statusCode = 200;
            // The code that inspects the request, adds response headers needed, and 
            // constructs a proper response body as string/stream.Readable
            this.sendResponse( context, { 
                status: statusCode, 
                headers: responseHeaders, 
                body: responseBody 
            });
        }
    }
      
    module.exports = TestRequestHandler;
    

    Replacing the default request handler

    After the server is initialized, the default request handler can be replaced with the server method loadHandler. The request handler object in the module has to be named as "default". See Request handler prototype above.


    API System

    ok-server has simple and easy facilities to create API services. These facilities includes means to define API requests, more specifically their names and parameters. API system will validate parameters of the requests and reponds with error message in case of invalid or missing parameters,

    API request is sent on client (browser) side as http requests with POST method. The API request name and the request parameters are added to the body of the http request as the json object.

    It also have two predefined API services.

    API-request

    The request object added to the body of the API request must be as follows.

    {
       name: string,
       parameters: {
        <parameter-name(1)>: boolean|number|object|string,
        ...,
        <parameter-name(n)>: boolean|number|object|string
       }
    }

    API request are done with the following function.

    function apiRequest( onError, onSuccess, name, parameters = {}) {
        
        const apiRoot = location.protocol + "//" + location.host + "/api";
        const request = { name: name, parameters: parameters };
        const xhr = new XMLHttpRequest();
        
        xhr.addEventListener( "error", () => { onError( new Error( "E_LOAD" ));});
        xhr.addEventListener( "abort", () => { onError( new Error( "E_ABORT" ));});
        xhr.addEventListener( "load", function () {
            try {
                const response = JSON.parse(this.responseText);
                if (response.succeed) {
                    onSuccess(response.content);
                }
                else {
                    onError(response.error);
                }
            }
            catch (error) {
                onError( new Error("E_PARSE: " + error.message ));
            }
        });
        xhr.open( "POST", apiRoot );
        xhr.setRequestHeader( "X-Requested-With", "XMLHttpRequest" );
        xhr.setRequestHeader( "Content-Type", "application/json; charset=utf-8" );
        xhr.send( JSON.stringify(request));
    }
    

    API-response

    The response payload to the API request contains a stringified json object. In case of success the json object is as follows.

    {
       succeed: true,
       requestName: string,
       content: array|boolean|number|object|string,
       elapsed: number
    }


    The response content property may contain the value of of any json-compatible data type. Elapsed property indicates the elapsed time of processing the request in milliseconds..

    In case of error the response payload contains following json object.

    {
       succeed: false,
       requestName: string,
       error: {
         code: string,
         message: string
       },
       elapsed: number
    }


    Pre-defined API requests

    api

    The content property of the response to the API request api contains complete specifications of the all currently implemneted API services as they are defined with okserver.defineApiRequest().

    {
       <request-name(1)>:
         parameters: {
           <parameter-name(1)>: {
             type: string,
             mandatory: boolean,
             description: object,
             default: boolean|number|object|string
           },
           ...,
           <parameter-name(n)>: {
             type: string,
             mandatory: boolean,
             description: object,
             default: boolean|number|object|string
           }
         },
         description: object,
         cargo: object
       },
       ...,
       <request-name(n)>: {
         ...
       }
    }

    This API service is especially useful for creating automatic client-side API module. See an example of the source file here.

    getConfig

    By default, the content property of the response to the api request getConfig contains an empty object. In order to include the desired values to the object the onApiGetConfig method of the OKServer can be overwritten and the content filled with the name-values pairs as wanted.


    Extending API

    Implementing API extension module

    The first thing is to create a new API extnesion module. Below is an example of the possible content of the module.

    const okserver = require("ok-server");
      
    okserver.defineApiRequest([ 
        { 
            name: "myService1", 
            parameters: {}, 
            worker: __myService1 
        },
        { 
            name: "myService2", 
            parameters: {
                firstname: {
                    type: "string",
                    mandatory: true,
                    description: { text: "First name" }
                },
                lastname: {
                    type: "string",
                    mandatory: true,
                    description: { text: "Last name" }
                },
                title: {
                    type: "string",
                    mandatory: false,
                    default: "Mrs."
                    description: { text: "Title" }
                }
            }, 
            worker: ( context ) => {
                // For array functions context is passed as function parameter
                const p = context.request.parameters;
                context.onSuccess( "Hello " 
                    + p.title + " " 
                    + p.firstname + " " 
                    + p.lastname + "!"
                );
            }
        }
    ]);
        
    function __myService1() {
        // In regular functions context is available as this keyword
        const ip = this.server.getRemoteIp( this.httpRequest ); 
        this.onSuccess(ip);
    }
    

    Loading API extension module

    API extension modules are loaded with OKServer extendApi method.

    Defining new API requests

    New API request is defined the API extension module with the OKServer method defineApiRequest.

    API worker functions

    The API request causes the worker function associated with it to be called. To this function is passed a Context object. If the function is an array function, Context object is passed as function parameter. In case of regular functions the context is available also as a value of this keyword.


    Reference

    Module ok-server

    Functions

    • okserver.createServer( options ) - Creates an OKServer object with the desired options.

      • options See server options.

        Return value: OKServer

    • okserver.defineApiRequest(definition) - Creates the definition of a new API service.

      • definition object
        {
           name: string,
           parameters: {
             <parameter-name(1)>: {
               type: string ("string"|"number"|"boolean"|"object")[,
               mandatory: boolean ][,
               default: string|number|boolean|object ][,
               description: object]
             },
             ...,
             <parameter-name(n)>: {
               type: string ("string"|"number"|"boolean"|"object")[,
               mandatory: boolean ][,
               default: string|number|boolean|object ][,
               description: object ]
             }
           },
           worker: function [,
           description: object ]
        }

      • Return value: none

    Properties

    • defaultOptions object - default options object whose values are used on creating and starting the server in the case these values are not overwritten in the options file or passed as the options parameter when creating the server. These option values are also written to the options file when it is created.
    • OKServer class - OKServer class for instantiating server object or extending one.
    • RequestHandler class - RequestHandler class for extending RequestHandler in order to create a new request handler.


    OKServer class

    Initialization

      new require("ok-server").OKServer(options);

    Options

    • accessFiltering array - Contains access filtering objects with following properties.

      • filter:
        • path string
        • status string ("forbidden"|"permitted")
    • apiEntryPoint string - Name of the virtual directory that serves as the entry point for the API requests. Default value is "api".

    • apiExtensions array - Full names of the API extension mofule files to be loaded before the server starts. Default is [].

    • cors object - Contains CORS related properties needed when client sends a pre-flight OPTIONS request.

      • allowCredentials boolean - If the allowCredentials is set as trua the Access-Control-Allow-Credentials response header is included into the response with value true. Default value is false.
      • allowHeaders string - Contains headers to be written in Access-Control-Allow-Headers response header. Default value is "authorization, content-type, x-requested-with".
      • allowOrigin string - Contains a comma-separated list of origins (or * character) against which the origin header of the request is checked. If the origin header of the request matches, it is written in the Access-Control-Allow-Origin header of the response. If the origins list contains the * character only, it is written in the Access-Control-Allow-Origin header. Default value is "*".
      • maxAge number - Contains a numeric value written in Access-Control-Max-Age response header. Default value is 7200.
    • defaultDirectory string - The full path of the root virtual directory. Default value is __dirname + "/examples/site".

    • defaultDirectoryName string - The name of the default directory that is set as the name for the root virtual directory. The default is "/".

    • defaultDocument string - Name of the default HTML document. Default value is "index.htm".

    • httpsOptions object - Contains options needed in creating HttpsServer. Can be either { pfx: string, passphrase: string } or { key: string, cert: string }. Default value is { pfx: "%OKSERVER_PFX%", passphrase: "%OKSERVER_PHRASE%" }. The value of the passphrase property may include - instead of a password - the name of the file that contains the actual password.

    • logApiRequests boolean - Indicates whether the API requests are written to the log file. Default value is false.

    • logFileRequests boolean - Indicates whether the file requests are written to the log file. Default value is false.

    • mimeTypes object - Includes MIME types supported by the server as the following object.

        {
          <extension(1)>: string,
          ...,
          <extension(n)>: string
        }

      OKServer supports following MIME types by default:

      • css text/css; charset=utf-8
      • htm text/html; charset=utf-8
      • html text/html; charset=utf-8
      • js application/javascript; charset=utf-8
      • json application/json; charset=utf-8
      • bmp image/bmp
      • gif image/gif
      • jpeg image/jpeg
      • jpg image/jpeg
      • png image/png
      • pnz image/png
      • tif image/tiff
      • tiff image/tiff
      • pfd application/pdf
      • txt text/plain; charset=utf-8
    • optionsFile string - The full name of the JSON options file where the server's options are read from. Options in the file are overwritten by the options passed as options parameter to the createServer function or OKServer constructor. Default value is __dirname + "options.json".

      Name of the JSON file where options are read from.

    • port number - Port number for the http.Server. If set as 0, the server is not instantiated. Default value is 3002.

    • pulseFolder string - Full name of the folder where the pulse file is written. The purpose of the Pulse is prevent the server starting if the script is re-run. If the options is not set, pulse does not start.

    • pulseInterval number - The interval as milliseconds where the pulse file is rewritten. Default value is 1000.

    • serverClass class - The class of the server object to create. It must be inherited from the OKServer. Default value is OKServer.

    • sslPort number - Port number for the https.Server. If set as 0, the server is not instantiated. Default value is 3002.

    • virtualDirectories object,
        {
          <name(1)>: { path: string, defaultDocument: string, handler: string },
          ...,
          <name(n)>: { path: string, defaultDocument: string, handler: string }
        }

    Methods

    • addForbiddenPath( path ) - Adds a forbidden path to the server. This path is not accessible for the client.

      • path string
      • return value: OKServer
    • addMimeType( fileExtension, type ) - Adds a new type into the server's supported MIME types list.

      • fileExtension string
      • type string
      • return value: OKServer
    • addPermittedPath( path ) - Adds a permitted path to the server. It is only meaninful if the parent of the added path is a forbidden path.

      • path string
      • return value: OKServer
    • addVirtualDirectory( params ) - Adds a new virtual directory to the server and associates a request handler for it.

      • params object
        • name string
        • path string
        • defaultDocument string - Default value is OkServer.defaultDocument.
        • handlerName string - Default value is "default".
        • parent VirtualDirectory - Default value is the base virtual directory creatad by the server according by the defaultDirectory and the defaultDirecotyName option values.
      • return value: string - Return value is a string that indicates the success of the action. In case of success, the value is "OK". The value E_UNKNOWNHANDLER indicates that the handlerName parameter refers to a non-loaded handler. The value E_PATHNOTFOUND indicates - when the path parameter is included - the folder to which the path is assigned does not exist. The value E_ALREADYEXISTS indicates that the virtual directory already exists.

    • extendApi(apiExtensionModule) - Extends the API system with new api extension modules.
      • apiExtensionModule string - The name of the module or array of module names as string values
      • return value: OKServer
    • getRemoteIp( request ) - Solves the remote IP address of the http request.
      • request http.IncomingMessage
      • return value: string

    • getVirtualDirectory( name, parent ) - Returns a virtual directory by it's full name.

      • fullname string - A string value representing the name of the directory as it is written in the URL address.
      • parent VirtualDirectory - The parent directory of the virtual directory to be retrieved. Default is the root virtual directory.
      • return value: VirtualDirectory
    • getVirtualDirectoryPath( name, parent ) - Returns the path of the virtual directory by the name of the directory.

      • name string - A string value representing the name of the directory as it is written in the URL address.
      • parent VirtualDirectory - The parent directory of the virtual directory to be retrieved. Default is the root virtual directory.
      • return value: string
    • isForbidden(url) -> boolean - Indicates whether the url points to a forbidden path. This method is is depracated

      • return value: boolean
    • isPermitted(url) -> boolean - Indicates whether the url points to a permitted path. This method is is depracated

      • return value: boolean
    • loadHandler( module|modulename ) - Loads a new request handler module

      • module string - The name of the module or module
      • return value: OKServer
    • removeMimeType(ext) - Removes a MIME type from the list of the supported MIME types.

      • return value: OKServer
    • setResponseCookie( response, cookie, encoder ) - Adds a cookie to the Http response by adding a Set-Cookie header.

      • response: http.ServerResponse
      • cookie object|array - Cookie object or array of cookie objects.
        • name string, mandatory
        • value string, default: "" (encoded with the encodeURIComponent function)
        • path string, default: "/"
        • domain string
        • expires Date
        • expirationDays number
        • maxAge number
        • httpOnly boolean
        • sameSite boolean (true: "strict", false: no sameSite attribute) or string ("strict"/"lax")
        • secure boolean
      • encoder function, default: encodeURIComponent
    • start( params ) - Starts the server i.e. the http.Server or https.Server or both.

      • params object
        • onError function(error) - Called in the case of error.
        • onSuccess function() - Called when server is started listening.
    • stop( onStop ) - Stops the server.

      • onStop function() - Called when server is stopped listening.
    • onApiApi( onError, onSuccess, context, iface ) - An event method that is triggered just before the response to the request api is sent. Provides an opportunity to modify API specifications, for example, to complete api documentation. Overwrite this in child class.

      • onError function(error) - To be called in the case of error.
      • onSuccess function(alteredIface) - The function must be called in order for the http response to be sent.
      • context Context - see requesthandler-api.js
      • iface object - API definitions object
    • onApiGetConfig( onError, onSuccess, context, config ) - An event method that is triggered just before the response to the request getConfig is sent. Provides the opportunity to complete the configuration data sent to the client. Overwrite this in child class.

      • onError function(error) - To be called in the case of error.
      • onSuccess function(alteredConfig) - The function must be called in order for the http response to be sent.
      • context Context - See requesthandler-api.js
      • config object - Configuration object that will be delivered as the response to the client's getConfig request.
    • onHttpReady() - An event method that is triggered when httpServer is started listening. Overwrite this in child class.

    • onHttpsReady() - An event method that is triggered when httpsServer is started listening. Overwrite this in child class.

    • onOptions(context) - An event method that is triggered when the client sends a request with OPTIONS method. This method fills in the required CORS related response headers. Overwrite this in child class when a different approach is needed.

    • onRequest(context) - An event method that is triggered before the actual handling of the request. Overwrite this in child class.

    • onResponse( context, params ) - An event method that is triggered the actual sending of the response. Overwrite this in child class.

      • context RequestContext - The RequestContext object.
      • params.status number - The Http Status code.
      • params.headers objects, Http response headrers.
      • params.body string/stream.Readable - The content for the response body.

    Properties

    • apiEntryPoint string - API entry point. Default is "api".
    • apiExtensions array (readonly) - Full names of the API extension mofule files to be loaded before the server starts.
    • defaultDirectory string - Full path of the root virtual directory.
    • defaultDirectoryName string - Name of the root virtual directory.
    • defaultDocument string - Default document.
    • httpServer http.Server (readonly) - Node.js http.Server object. Property is undefined if the port option is set as 0.
    • httpsOptions object (readonly) - Server options as object.
    • httpsServer https.Server (readonly) - Node.js https.Server object. Property is undefined if the sslPort option is set as 0.
    • logApiRequests boolean - Indicates whether API requests are written in to the log file.
    • logFileRequests boolean - Indicates whether file requests are written in to the log file.
    • mimeTypes object (readonly) - Includes MIME types the server is supporting.
    • port number - http.Server port number .
    • root VirtualDirectory (readonly) - Root virtual directory created based on defaultDirectory and defaultDirectoryName properties.
    • sslPort number - https.Server port number.

    VirtualDirectory class

    Initialization

    VirtualDirectory objects are initialized by the OKServer and are accessible with the method getVirtaulDirectory or - in case of the root virtual directory - with the property root.

    Properties

    • defaultDocument string - Name of the default document.
    • fullname string - The full name of the directory as it is written in the URL address.
    • handler RequestHandler - The request handler associated to the virtual directory.
    • handlerName string - The name of the handler associated to the virtual directory.
    • name string - Name of the virtual directory.
    • path string - Virtual directory path.
    • parent VirtualDirectory - Parent virtual directory.

    Context class

    Initialization

    Context objects are initialized by the OKServer's API System and passed to a API services' worker functions as the first parameter (and also as #this# keyword if the worker function is not an array function).

    Properties

    • cookies object - Request cookies as an object.
    • httpRequest http.IncomingMessage - Request as the node.js IncomingMessage object.
    • httpResponse http.ServerResponse - Response as the node.js ServerResponse object.
    • onError callback function(Error) - A callback function to be called in the case of error.
    • onSuccess callback function(responseContent) - A callback function to be called in the case of success. The responseContent parameter will be assigned as the value of the content property of the API response object.
    • request reuest API request object as it is in http request body.
    • requestHandler ApiRequestHandler - ApiRequestHandler object.
    • requestName string - The name of the request made by a client.
    • server OKServer - The instance of OKServer.
    • started number - The request time as milliseconds (Date().getTime()).

    RequestContext class

    Initialization

    RequestContext objects are initialized by the OKServer on every client request and passed to the appropriate request handler as the only parameter of the onRequest method.

    Properties

    • cookies object - Requests cookies.
    • handler RequestHandler - Request Handler object.
    • handlerName string - Name of the Request Handler serving the request.
    • origin string - The content of the request's origin header.
    • path string - The path in request URL.
    • pathName string - The path in request URL.
    • physicalPath string - The full physical path of the virtual directory to which the request URL indicates.
    • request http.IncomingMessage - Request as the node.js IncomingMessage object.
    • response http.ServerResponse - Response as the node.js ServerResponse object.
    • server OKServer - The instance of the OKServer.
    • url object - Server's url parsed to the node.js URL object.
    • virtualDirectory VirtaulDirectory - The virtual direcory object the request url pathname points to.

    Methods

    • isForbidden() -> boolean - Indicates whether the path which the http request is pointing to is forbidden. This method is automaticly called by the server.

      • return value: boolean
    • setResponseCookie( cookie, encoder ) - Adds a cookie to the Http response by adding a Set-Cookie header.

    • solveAllowedOrigin() -> string - Returns RequestContext.origin if it is included in the list of allowed origins in the server settings or if the allowed origin setting contains the * character. This method is automaticly called by the server.

      • return value: boolean

    Module requesthandler

    Functions

    • requesthandler.getHandler( handlerName ) - Get the Request Handler object by it's name.
      • handlerName string - Name of the handler.
      • Return value: object - Request Handler object inherited from RequestHandler.

    Properties

    • RequestHandler class RequestHandler - The RequestHandler class for the Request Handler inheritance.

    RequestHandler class

    Initialization

    Objects inherit from RequestHandler are instantiated by the OKServer when loadHandler method is called.

    Properties

    • options object - Shortcut to OKServer.options
    • server OKServer - OKServer object.

    Methods

    • getRemoteIp( request ) - Shortcut to OKServer.getRemoteIp().

      • request http.IncomingMessage
      • Return value: string - IP address as string.
    • sendResponse( context, params ) - Sends response to the client.

      • context: RequestContext - RequestContext object.
      • params object
        • status number - The Http Status code. Default value is 200.
        • headers objects - Http response headrers. Default value is {}.
        • body string/stream.Readable - The content for the response body. Default value is undefined (means that the response body is not included).
    • setResponseCookie( response, cookies, encoder ) - See OKServer.setResponseCookie()

    • solveMimeName( extension ) - Get MIME Type by file extension.

      • extension string - File extension.
      • Return value: string - MIME type.
    • onRequest( context ) - OKServer calls this method for every client request addressed to the handler of the method. onRequest should handle sending of a response to the client.

    • decodeURI( uri )

      • uri string - URI string.
      • Return value: string - Decoded URI string.

    Install

    npm i ok-server

    DownloadsWeekly Downloads

    1

    Version

    1.0.5

    License

    MIT

    Unpacked Size

    137 kB

    Total Files

    21

    Last publish

    Collaborators

    • ollikekalainen