- DelphiTools - https://www.delphitools.info -

DWScript WebServer in the metered cloud

web_serverI’ve now been running the DWScript Sample Web Server [1] for 8 months in a metered host (Ikoula’s 1€/month VM [2]), so it’s time for a more formal introduction article.

It served web pages and JSON dynamically generated by DWScript [3], using an SQLite [4] database for storage. It ran on a Windows 2008 R2 Standard installation, minimized so that OS+Server stayed around 256 MB RAM.

I didn’t mention it much before I grew confident that, provided you’re careful, you can indeed run a Windows-based, high-performance Pascal-based web server at a very low cost, even lower than most Linux-based VPS and with a higher performance than the cheaper Linux options.

DWScript Web Server

The DWScript Sample Web Server [1] source can be found in the Demos\HttpSys2WebServer [5] folder of the DWScript source code.

The executable can run both as an application and a windows service. Though it can be used on its own merits, it’s more intended as a starting point/demonstrator.

webserver_live

Server live information page (cf. sample website)

HTTP.SYS

The HTTP Server API [8] is is the foundation upon which IIS or WCF are built, it’s a low-level, high-performance server layer that allows multiple services to share the same http port. Security-wise, for the wild web it handles SSL, and for intranets, it can handle NTLM and Kerberos domain authentication.

What this means in practice is that you can use the DWS Web Server to handle just a portion of traffic of a website, leaving the rest to IIS, WCF services, or other HTTP.SYS-capable servers like mORMot. On an Entreprise network, it means you benefit from Windows Domain Single-Sign On for all three major browsers (Chrome, FireFox, and Internet Explorer).

To use http.sys, there are some restriction which involve administrative rights at least at some point. To run the server executable you need to ensure at least one of the following:

For the last option, you’ll need to use the netsh http add urlacl [9] command. To enable SSL, you’ll need to register your certificate [10] (for testing purposes, you can get a free SSL certificate from StartSSL [11]).

You can also use HttpSysConfig [12] or HttpSysManager [13], if you prefer GUI tools. They are very basic, but I’ve found you usually won’t need to do much in the way of http.sys administration.

HTML Filter

Though it has ‘html’ in its name, the filter can be used for generating just anything really (css, js, json, xml, or even Pascal). In the DWS Web Server, it’s paired with the WebEnvironment [14] module, which if still limited, provides access to HTTP request and response details.

It’s named “filter” because it works by turning a “.dws” file into a Pascal program, which will then be executed. For instance the following “.dws” source

<h1><?pas=FormatDateTime("yyyy-mm-dd", Now)?></h1>
<p><?pas
for var i := 1 to 3 do
   PrintLn(i*10);
?></p>

would be filtered to the following Pascal source

Print('<h1>');
Print(FormatDateTime("yyyy-mm-dd", Now);
Print('</h1>'#13#10'<p>');

for var i := 1 to 3 do
   PrintLn(i*10);

Print('</p>');

which if executed on the 13th of August 2013 would generate

<h1>2013-08-13</h1>
<p>10
20
30
</p>

So to summarize <?pas ?> delimiters encapsulates Pascal statements, and <?pas= ?> encapsulate a Pascal expression. The delimiters can be adjusted in the TdwsHTMLFilter component, and besides being powerful, the whole filtering+script combination is very competitive performance-wise.

The TdwsHtmlFilter got various performance enhancement, but mostly dates back to the early days of DWScript, so it’s a kinda the original essence of DWScript programming.

You can easily make a syntax highlighting editor for .dws files with SynEdit [15], use a TSynMultiSyn component to combine the HTML highlighter with the DWS highlighter (and probably the JS and CSS highlighter as well, if you want a complete solution).

DWS engine

dws-mirrorIn the sample web server, pages (aka scripts) are compiled only once, then executed multiple times, with parallel executions of the same page being possible. The engine is coupled with http.sys through IOCP [16].

A TdwsFileNotifier (which also uses IOCP) watches the website directory and invalidates compiled scripts when necessary, this means you can edit the .dws & .pas files, and just hit F5 in your browser to see the result.

By default DataBase [17] and JSON [18] modules are active in the sample Web Server. The DataBase modules provides simple, high-performance connectivity to just about any DB out there (see previous article [19]), thanks to mORMot SynDB and UIB components. The JSON connector (cf. article [20]) allows to efficiently parse and generate JSON, with a lightweight syntax very close to what you would use in JavaScript.

While these provide a lot of capability, you can and should of course use your own modules as well to expose business or other functionality to your scripts.

Since DWS is under a sand-boxed model, script users will only be able to access what functionality you expose them. The engine is also aiming at safeguarding for issues that might plague ISAPI DLLs or native Delphi-based servers, such as dangling pointers, memory leaks or infinite loops.