Proxy Server - SGApps.IO

pipeline status Repository - GitLab Documentation Sergiu Gordienco email sergiu.gordienco@gmail.com

A user-friendly library that creates a ProxyServer oriented to redirect traffic to other URL addresses

You may use it to redirect traffic, OR as a firewall to control traffic to a Virtual Machine on your server.

there are a lot of ways to use it.

by Sergiu Gordienco Vasile ( email: sergiu.gordienco@gmail.com )

https://labs.sgapps.io/open-source/proxy-server/


Integration with expressjs / httpServer / httpsServer

in similar way you can integrate this server on an existing site / or other HTTP/HTTPS Server

npm install --save @sgapps.io/proxy-server
const proxyServerBuilder = require("@sgapps.io/proxy-server");
const express = require("express");

let app = express();
let configuration = require("./config.js");

// initialize proxy server only as a request handler
let proxyServer = proxyServerBuilder(configuration, false);

// connect proxy server to express server
proxyServer((server) => {
    app.all(
        (req, res) => {
            server.handleRequest(req, res);
        }
    );


    server.on("onError", function (err) {
        // ...
    });
    server.on("onLog", function (message1, message2, messageN) {
        // ...
    });

});

app.listen(8080);
  • server.configuration - returns configuration object
  • server.debugEnabled([boolean]) - switch debug option
  • server.debugEnabled() - debug return current debug option
  • server.isRunning() - returns running status
  • server.close(callback) - callback function recieves error if error ocurred
  • server.handleRequest(request, response) - handle HTTP Request / Response
  • server.httpServer() - returns a http.createServer()

Using as a CLI Command

  • Installing
npm install -g @sgapps.io/proxy-server
  • Running

    sgapps-proxy-server --config /path/to/your-config-file.json

Using @sgapps.io/proxy-server as a server

    const proxyServerBuilder = require("@sgapps.io/proxy-server");

    let proxyServer = proxyServerBuilder({
        httpServer : {
            host : "0.0.0.0",
            port : 80
        },
	defaultProtocol: "http", // optional, default is http
	secureVerify   : false, // disable SSL Certificate validation
        proxyRules : [
            {
                client_port : 80,
                client_host : "sgapps.io",
                domains	 : [
                    "www.js.md",
                    "html5.md",
                    "www.html5.md",
                    "html.md",
                    "www.html.md",
                    "javascript.md",
                    "www.javascript.md",
                    "nodejs.md",
                    "www.nodejs.md"
                ]
            },
            {
                client_port	: 6080,
		protocol	: "https",
                // host will be localhost
                domains	: [
                    'www.first-jump.com',
                    'first-jump.com',
                    'cloudwebcode.com',
                    'www.cloudwebcode.com'
                ]
            }
        ],
        debug: true
    });


    // accessing server to log errors
    proxyServer(function (server) {
        // function will be called when server will be ready
        server.on("proxy-error", function (err, req, res) {
            console.error(err);
        });

        server.on("onError", function (err) {
            // ...
        });
        server.on("onLog", function (message1, message2, messageN) {
            // ...
        });
    });

Set a custom Error Page for ProxyServer

// ... initialize server

proxyServer((server) => {
    server.off("proxy-error", "response-error-render");

    server.on("proxy-error", function (err, request, response) {
            response.statusCode = 500;
            response.write(
                `<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Proxy Eror</title>
</head>
<body>
    Opps, Proxy Error...
</body>
</html>`
            );
            response.end();
        },
        "response-error-render"
    );
});

Contribution

if you find code interesting you may participate by updating documentation using pull request or mail messages to mailto:sergiu.gordienco@gmail.com

License of Application Prototype

Creative Commons License Creative Commons Attribution-NonCommercial 4.0 International License Creative Commons License - Creative Commons Attribution-NonCommercial 4.0 International License

JS Application Builder by JavaScript Application Builder is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License. Based on a work at http://sgapps.io. Permissions beyond the scope of this license may be available at http://sgapps.io.

API

Table of Contents

Handler

Type: Function


ProxyServer

Type: function ()


debugEnabled

check if debug mode is enabled

Type: function (): boolean


debugEnabled

enable disable debug mode

Type: function (status): boolean


error

log a error if debug mode is enabled

Type: function (err)


log

logs if debug mode is enabled

Type: function (items)

  • items ...any

handleRequest

handle for http server request / response

Type: function (request, response)


configuration

returns proxy current configuration

Type: function (): SGAppsProxy.Config


string2Rule

converts a string rule into regular expression ( case sensitive )

Type: function (rule): RegExp

  • rule string example "*.sgapps.io"

close

close ProxyServer

Type: function (cb)

  • cb Function callback receives an error if it occurs

isRunning

check if ProxyServer is running, it returns null if no http server is attached to ProxyServer

Type: function (): boolean


proxyServer

return proxy instance

Type: function (): ProxyServer


httpServer

returns http server user by ProxyServer return type Server

Type: function (): object


responseRenderPath

render a file in response, file piped to response

Type: function (response, path)


Cache

Type: object


protocol

returns current used protocol

Type: function (defaultProtocol): string

  • defaultProtocol string? if is empty returns configuration default protocol

SGAppsProxy

Type: function ()


ParsedUrl

Type: object


ProxyRule

Type: object

  • client_host string ( ex: '127.0.0.1' )
  • client_port number ( ex: 80 )
  • domains Array<string> array or domain mappers ( ex: "*.sgapps.io" )
  • client_path string? ( ex: '/some/path/' )
  • protocol (string | "http" | "https")? ( ex: null or 'username:password' )
  • proxyFilter SGAppsProxy.ProxyFilter
  • proxyRefs object
  • proxyOptions SGAppsProxy.ProxyOptions
  • proxyOptionsHandler SGAppsProxy.ProxyOptionsHandler

ProxyFilter

if returns null the proxy server will not continue to parse flow if returns false the proxy server will ignore rule if returns true the proxy server will accept rule if returns Error the proxy will accept render error page

Type: Function

  • proxyRefs object
  • proxyOptions SGAppsProxy.ProxyOptions
  • request Request
  • response Response
  • rule SGAppsProxy.ProxyRule
  • cache SGAppsProxy.ProxyServer.Cache

ProxyOptionsHandler

if returns null the proxy server will not continue to parse flow

Type: Function

  • proxyOptions SGAppsProxy.ProxyOptions
  • request Request
  • response Response
  • cache SGAppsProxy.ProxyServer.Cache

ProxyOptions

Type: object

  • target string? url string to be parsed with the url module
  • forward string? url string to be parsed with the url module
  • agent object? object to be passed to http(s).request (see Node's https agent and http agent objects)
  • ssl object? object to be passed to https.createServer()
  • ws boolean? true/false, if you want to proxy websockets
  • xfwd boolean? true/false, adds x-forward headers
  • secure boolean? true/false, if you want to verify the SSL Certs
  • toProxy boolean? true/false, passes the absolute URL as the path (useful for proxying to proxies)
  • prependPath boolean? true/false, Default: true - specify whether you want to prepend the target's path to the proxy path
  • ignorePath boolean? true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request (note: you will have to append / manually if required).
  • localAddress string? Local interface string to bind for outgoing connections
  • changeOrigin boolean? true/false, Default: false - changes the origin of the host header to the target URL
  • preserveHeaderKeyCase boolean? true/false, Default: false - specify whether you want to keep letter case of response header key
  • auth string? Basic authentication i.e. 'user:password' to compute an Authorization header.
  • hostRewrite boolean? rewrites the location hostname on (201/301/302/307/308) redirects.
  • autoRewrite boolean? rewrites the location host/port on (201/301/302/307/308) redirects based on requested host/port. Default: false.
  • protocolRewrite boolean? rewrites the location protocol on (201/301/302/307/308) redirects to 'http' or 'https'. Default: null.
  • cookieDomainRewrite boolean? rewrites domain of set-cookie headers. Possible values: false (default): disable cookie rewriting String: new domain, for example cookieDomainRewrite: "new.domain". To remove the domain, use cookieDomainRewrite: "". Object: mapping of domains to new domains, use "*" to match all domains. For example keep one domain unchanged, rewrite one domain and remove other domains:cookieDomainRewrite: { "unchanged.domain": "unchanged.domain", "old.domain": "new.domain", "*": "" }
  • cookiePathRewrite boolean? rewrites path of set-cookie headers. Possible values: false (default): disable cookie rewriting String: new path, for example cookiePathRewrite: "/newPath/". To remove the path, use cookiePathRewrite: "". To set path to root use cookiePathRewrite: "/". Object: mapping of paths to new paths, use "*" to match all paths. For example, to keep one path unchanged, rewrite one path and remove other paths:cookiePathRewrite: { "/unchanged.path/": "/unchanged.path/", "/old.path/": "/new.path/", "*": "" }
  • headers object? object with extra headers to be added to target requests.
  • proxyTimeout number? timeout (in milliseconds) for outgoing proxy requests
  • timeout number? timeout (in milliseconds) for incoming requests
  • followRedirects boolean? true/false, Default: false - specify whether you want to follow redirects
  • selfHandleResponse boolean? true/false, if set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the proxyRes event
  • buffer Buffer? stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called 'req.rawbody' you could restream this field in the buffer option:'use strict';const streamify = require('stream-array'); const HttpProxy = require('http-proxy'); const proxy = new HttpProxy();module.exports = (req, res, next) => {proxy.web(req, res, { target: 'http://localhost:4003/', buffer: streamify(req.rawBody) }, next);};
  • response object?
    • response.headers object headers to be merger to response headers

Config

Type: object


SGAppsProxy

SGApps.io / Proxy Server

Type: function (configuration, httpServerInstance): SGAppsProxy.Handler

  • configuration SGAppsProxy.Config
  • httpServerInstance httpServer

Meta

  • author: Sergiu Gordienco Vasile

ParsedUrl

Type: object


ProxyRule

Type: object

  • client_host string ( ex: '127.0.0.1' )
  • client_port number ( ex: 80 )
  • domains Array<string> array or domain mappers ( ex: "*.sgapps.io" )
  • client_path string? ( ex: '/some/path/' )
  • protocol (string | "http" | "https")? ( ex: null or 'username:password' )
  • proxyFilter SGAppsProxy.ProxyFilter
  • proxyRefs object
  • proxyOptions SGAppsProxy.ProxyOptions
  • proxyOptionsHandler SGAppsProxy.ProxyOptionsHandler

ProxyFilter

if returns null the proxy server will not continue to parse flow if returns false the proxy server will ignore rule if returns true the proxy server will accept rule if returns Error the proxy will accept render error page

Type: Function

  • proxyRefs object
  • proxyOptions SGAppsProxy.ProxyOptions
  • request Request
  • response Response
  • rule SGAppsProxy.ProxyRule
  • cache SGAppsProxy.ProxyServer.Cache

ProxyOptionsHandler

if returns null the proxy server will not continue to parse flow

Type: Function

  • proxyOptions SGAppsProxy.ProxyOptions
  • request Request
  • response Response
  • cache SGAppsProxy.ProxyServer.Cache

ProxyOptions

Type: object

  • target string? url string to be parsed with the url module
  • forward string? url string to be parsed with the url module
  • agent object? object to be passed to http(s).request (see Node's https agent and http agent objects)
  • ssl object? object to be passed to https.createServer()
  • ws boolean? true/false, if you want to proxy websockets
  • xfwd boolean? true/false, adds x-forward headers
  • secure boolean? true/false, if you want to verify the SSL Certs
  • toProxy boolean? true/false, passes the absolute URL as the path (useful for proxying to proxies)
  • prependPath boolean? true/false, Default: true - specify whether you want to prepend the target's path to the proxy path
  • ignorePath boolean? true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request (note: you will have to append / manually if required).
  • localAddress string? Local interface string to bind for outgoing connections
  • changeOrigin boolean? true/false, Default: false - changes the origin of the host header to the target URL
  • preserveHeaderKeyCase boolean? true/false, Default: false - specify whether you want to keep letter case of response header key
  • auth string? Basic authentication i.e. 'user:password' to compute an Authorization header.
  • hostRewrite boolean? rewrites the location hostname on (201/301/302/307/308) redirects.
  • autoRewrite boolean? rewrites the location host/port on (201/301/302/307/308) redirects based on requested host/port. Default: false.
  • protocolRewrite boolean? rewrites the location protocol on (201/301/302/307/308) redirects to 'http' or 'https'. Default: null.
  • cookieDomainRewrite boolean? rewrites domain of set-cookie headers. Possible values: false (default): disable cookie rewriting String: new domain, for example cookieDomainRewrite: "new.domain". To remove the domain, use cookieDomainRewrite: "". Object: mapping of domains to new domains, use "*" to match all domains. For example keep one domain unchanged, rewrite one domain and remove other domains:cookieDomainRewrite: { "unchanged.domain": "unchanged.domain", "old.domain": "new.domain", "*": "" }
  • cookiePathRewrite boolean? rewrites path of set-cookie headers. Possible values: false (default): disable cookie rewriting String: new path, for example cookiePathRewrite: "/newPath/". To remove the path, use cookiePathRewrite: "". To set path to root use cookiePathRewrite: "/". Object: mapping of paths to new paths, use "*" to match all paths. For example, to keep one path unchanged, rewrite one path and remove other paths:cookiePathRewrite: { "/unchanged.path/": "/unchanged.path/", "/old.path/": "/new.path/", "*": "" }
  • headers object? object with extra headers to be added to target requests.
  • proxyTimeout number? timeout (in milliseconds) for outgoing proxy requests
  • timeout number? timeout (in milliseconds) for incoming requests
  • followRedirects boolean? true/false, Default: false - specify whether you want to follow redirects
  • selfHandleResponse boolean? true/false, if set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the proxyRes event
  • buffer Buffer? stream of data to send as the request body. Maybe you have some middleware that consumes the request stream before proxying it on e.g. If you read the body of a request into a field called 'req.rawbody' you could restream this field in the buffer option:'use strict';const streamify = require('stream-array'); const HttpProxy = require('http-proxy'); const proxy = new HttpProxy();module.exports = (req, res, next) => {proxy.web(req, res, { target: 'http://localhost:4003/', buffer: streamify(req.rawBody) }, next);};
  • response object?
    • response.headers object headers to be merger to response headers

Config

Type: object


ApplicationPrototype

Type: function ()