Scripting Server

Getting Started

Scripting Server is a web application that provides for a runtime environment into which applications written in JavaScript can be deployed.

Overview

The Scripting Server consists of three parts:

An general status page is located at the root of the web application, the relative URL /.

The administrative functions are used to

Administrative functions are only provided on port 8088, while the other functions are available on port 8080. The administrative port can be set with adminPort in web.xml.

The default configuration allows only static deployment of scripts. To enable uploading scripts to the server using the administrative interface, change the scriptUpload setting in web.xml to enabled.

The scripting environment itself passes incoming requests to the JavaScript application previously deployed into the scripting environment.

Initially and after a restart, the scripting environment does not contain any application code and will report an error for any requests directed at it.

After an application has been deployed into the scripting environment, HTTP requests to a relative URL starting with /se are passed to a request handler in the JavaScript application. The application then performs the required processing and prepares a HTTP response.

Anatomy of the scripting environment

Any JavaScript runtime environment has a top level scope, also called the global object.

The global object is where all global variables (all variables not declared with the "var" statement) are located.

Functions in JavaScript are objects as well, usually identified by a global variable with the name of the function. Whenever JavaScript code executes, a function call is actually a lookup for a variable of that name in the global object. The code contained by the function object can then be executed, possibly with arguments passed to it.

Function objects are created whenever a script declares a function using the "function" keyword. Even after a script is executed, the function remains part of the global object. Subsequent script executions for the same global object can call a previously declared function.

The scripting environment is a global object that is created initially and after each restart. It is initialized by the config.js script, which declares all standard functions, classes and constants.

Preparing the stage

Scripts that resemble the application are either read from a dedicated application directory (see Static Deployment below) or are posted to the serevr using the POST method of HTTP. POST requests must be directed to the administrative URL (/admin). Script received by the server are immediately compiled and executed under the scope of the global object.

For security reasons, the default configuration rejects to execute scripts send with POST. This feature must be enabled by setting scriptUpload to enabled in the web.xml configuation file contained in the .war file.

The global object is enriched with new function objects by each script executed on the server. Each script can provide new functionality to other scripts loaded later on, effectively assembling the parts on an application.

One of the scripts must declare a function with the name "handleRequest()". Once this function is declared, the scripting environment is operational and ready to process requests.

Processing requests

All requests for a URL starting with /se are passed to the handleRequest() function in the global object. The function is called with a request and a response object. The request object contains informations about the request, whereas the response object is used by the application to prepare the response to the caller.

For each invocation of the handleRequest() function, the Scripting Server creates a so called dynamic scope. A dynamic scope looks to the application like a global object, but effectively it is just created for this single request processing. In contains all global variables and functions previously declared, but new global variables created during request processing are discarded after the request completes. Each request starts with a clean, pre-configured global object.

Data that must be shared between requests must be stored in an object anchored in the global object.

Hello World

The Hello World application prepares a simple HTML page for each incoming request:

//
// The Hello World application
// 

function handleRequest(req, res) {
	GPSystem.trace("Request received.");
	var page =
		<html>
			<head>
				<title>Scripting Server - Hello World</title>
			</head>
			<body>
				<p>Hello World</p>
			</body>
		</html>
		
	res.print(page.toXMLString());
}

The Hello World application is available as helloworld.js script in den js directory of the server bundle.

The script can be uploaded into the server using the curl command line tool. A version of curl is included in the bin directory of the server bundle.

The command line

   > curl -T helloworld.js http://localhost:8088/admin

uploads the script to the server. Using http://localhost:8080/se in your browser should display the Hello World page generated by the script.

Static deployments

While dynamic deployment using a HTTP post is suitable for development and testing, static deployment provides for a more production ready setup.

In static deployment, the scripting code is either bundled with the web application or provided on the local file system.

To load static deployments, the scripting server tries to locate the file apps/startup.js in GPSystem.SYS or GPSystem.USR. GPSystem.SYS is located in WEB-INF/js in the .war archive, GPSystem.USR is mapped to /var/lib/scriptingserver/<contextroot> using the parameter userDir in web.xml.

In a development environment GPSystem.USR is often located outside /var/lib/scriptingsserver. Rather than changing userDir in web.xml, you can define an environment variable SCRIPTINGSERVER_USERDIR which overrides the setting in web.xml or the default setting.

Example: If you set SCRIPTINGSERVER_USERDIR=/home/foo/project and the ScriptingServer is deployed to the root context of the servlet container (/ [default]), then it will try to load /home/foo/project/apps/startup.js. If you run multiple ScriptingServer instances and deploy to different context roots (e.g. /eacpki), then the server will look in /home/foo/project/eacpki/apps/startup.js.

Security considerations

Care must be taken if the ScriptingServer is connected to the Internet.

Access to /admin is only available on port 8088, which should not be reachable from the Internet. Also in a production environment, the upload of scripts via /admin must be disabled (default) to prevent an attacker from uploading malicous scripting code into the server gaining full access to the system.

If you want to connect a Scripting Server instance to the Internet, we recommend to run the server behind an Apache Reverse Proxy. Such a proxy can be configured using mod_proxy and the following statements in your site configuration:

	ProxyRequests off
	ProxyPass /se http://127.0.0.1:8080/se
	ProxyPassReverse /se http://127.0.0.1:8080/se

In this configuration the ScriptingServer runs locally on port 8080 and only requests to /se are forwarded to the server. Access to / and /admin is not possible from the outside. Scripts should be deployed statically.

If your applications is using static content, then this should be placed on the Apache server.