Having to Do More

The days of the Desktop PC as the Web client are fading away. Growth comes from many devices – the Internet of things:

2000's ..... Apple ......... Mobile Internet ...... 10 (Units, in Billions)

1990's ..... Google ........ Desktop Internet ..... 1

1980's ..... Microsoft ..... Desktop PC ........... 0.1

To cope with the geometric growth of these new Internet clients, much more scalable servers are needed. G-WAN is significantly faster and scalable than others, but it is also much easier it is to use.

G-WAN also is safer by-design: adaptive timeouts (rather than fixed-values in config files) let G-WAN automatically block many DoS (Denial of Service) attacks. And unlike Apache or Nginx, G-WAN allocates memory on-demand (rather than upfront), making it possible to both use far less memory and scale as needed (instead of blocking when the limit of concurrent clients is reached).

With nearly all works billed by the hour, ease-of-use and efficiency reduce your costs and therefore boost your margins.

In your favorite <scripted> language

Use asm C C++ C# D Go Java Javascript Lua Objective-C Perl PHP Python Ruby and Scala scripts with G-WAN. With scripts for both compiled and interpreted languages, G-WAN delivers the productivity that has made less efficient frameworks popular for Web development. (click on language tags to get benchmarks, see them all here)

Why are scripts so useful?

You test your code "live" by just pressing F5 in the Web browser. With Apache, Lighttpd or Nginx C source code modules you have to stop the server, recompile it, and then redeploy it – each time you need to change your code.

G-WAN offers the most of both worlds: efficiency and convenience.

A SERVLET example: 'Hello World'

Servlets are scripts which let G-WAN build dynamic replies for client requests.

By default, C is the "default" language: client requests can ommit the .c file extension ( /?hello.c can be invoked as /?hello ). You can assign this feature to your favorite language. You can also replace the ? (query character) by any character among the URI non-reserved list: - _ . ! ~ * ' ( ) (see DEFAULT_LANG and QUERY_CHAR ).

Deploying one of the servlets below is as simple as copying a source code file in the gwan/.../csp directory:

C

C++

C#

Go

Java

Javascript

Lua

Objective-C

Perl

PHP

Python

Ruby

Scala hello.c This C script is invoked as follows: http://localhost/?hello.c 1 2 3 4 5 6 7 #include "gwan.h" // G-WAN API int main ( int argc, char *argv[]) { xbuf_cat ( get_reply (argv), "Hello World" ); return HTTP_200_OK ; // HTTP status code } To change the behavior of hello.c , edit its source code (G-WAN will always serve the latest version saved on disk). Compare these 7 lines of code to the 120-line Nginx 'Hello World' module (that needs a dedicated configuration file). hello.cpp This C++ script is invoked as follows: http://localhost/?hello.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 #include "gwan.h" // G-WAN API #include <string> using namespace std; class Hello{ public : void whatsup (xbuf_t *reply, string & str) { xbuf_cat ( reply , ( char *) str.c_str ()); } }; int main ( int argc, char *argv[]){ string h( "Hello World" ); Hello hello ; hello.whatsup ( get_reply (argv), h); return HTTP_200_OK ; // HTTP status code } hello.cs This C# script is invoked as follows: http://localhost/?hello.cs 1 2 3 4 5 6 7 8 9 10 using System; public class hello { public static int Main ( string [] args) { Gwan.xbufCat ( Gwan.getReply (args[0]), "Hello World" ); return 200; // HTTP status (200:'OK') } } Unsurprisingly, C# having been designed to compete with Java, hello.java and hello.cs are very similar. In our tests , Mono performed slightly better than the JVM , both in performance and memory usage. hello.java This Java script is invoked as follows: http://localhost/?hello.java 1 2 3 4 5 6 7 8 9 10 import api.Gwan; public class hello { public static int jmain ( long env, String [] args) { Gwan.xbufCat ( Gwan.getReply (env), "Hello World" ); return 200; // HTTP status (200:'OK') } } Java is "specifically designed to have as few implementation dependencies as possible. Java applications are compiled to bytecode (class file) running on the Java virtual machine (JVM)" written in C. hello.scala This Scala script is invoked as follows: http://localhost/?hello.scala 1 2 3 4 5 6 7 8 9 10 import api.Gwan; object hello { def jmain int (env: Long , args: Array[String]) : Int =) { Gwan.xbufCat ( Gwan.getReply (env), "Hello World" ); return 200; // HTTP status (200:'OK') } } Scala is based on the JVM (Java Virtual Machine) and aims at making it easier to do parallel-programming tasks. hello.php This PHP script is invoked as follows: http://localhost/?hello.php 1 2 3 4 <?php echo "Hello World

" ; exit (200); // HTTP status (200:'OK') ?> In this example PHP is 'simpler' because no function was defined and no G-WAN API calls were used (but since the original PHP runtime is used, your options are not limited). The same goes for Javascript, Lua, Perl, Python, Ruby, etc. hello.go This Go script is invoked as follows: http://localhost/?hello.go 1 2 3 4 5 6 7 8 9 10 package main import "fmt" import "os" // having the next brace down to the next line gives a syntax error func main () { fmt.Printf ( "Hello World" ) os.Exit (200) // return an HTTP code (200:'OK') } Like Scala, Google 'Go' is a relatively new language which aims at making it easier to write high-concurrency applications. hello.py This Python script is invoked as follows: http://localhost/?hello.py 1 2 3 4 5 import os import sys print 'Hello World' sys.exit (200) // return an HTTP code (200:'OK') Python is an high-level language which "supports multiple programming paradigms, including object-oriented, imperative and functional programming or procedural styles". hello.pl This Perl script is invoked as follows: http://localhost/?hello.pl 1 2 3 print "Hello World"; exit 200; # return an HTTP code (200:'OK') Perl is an high-level language which "gained widespread popularity in the late 1990s as a CGI scripting language, in part due to its parsing abilities". hello.rb This Ruby script is invoked as follows: http://localhost/?hello.rb 1 2 3 puts 'Hello World'; exit (200); # return an HTTP code (200:'OK') Ruby is an high-level language which "dynamic, reflective, and object-oriented design combines a syntax inspired by Perl with Smalltalk-like features". hello.lua This Lua script is invoked as follows: http://localhost/?hello.lua 1 2 3 io.stdout:write ( "Hello World" ) os.exit (200) -- return an HTTP code (200:'OK') Lua is an high-level language which "lightweight multi-paradigm design targets 'extensible semantics' as a primary goal". hello.js This Javascript script is invoked as follows: http://localhost/?hello.js 1 2 3 console.log ( "Hello World" ) process.exit (200); // return an HTTP code (200:'OK') Javascript is an high-level language which was "originally implemented as part of web browsers. More recently, it has been used in server-side programming". hello.m This Objective-C script is invoked as follows: http://localhost/?hello.m 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #import "gwan.h" // G-WAN API #import <objc/Object.h> @interface Hello : Object { xbuf_t*replyBuffer; } - (Hello*)initWithBuffer:(xbuf_t*) reply; - ( void )whatsup; @end @implementation Hello - (Hello*)initWithBuffer:(xbuf_t*) reply { replyBuffer = reply; return self; } - ( void )whatsup { xbuf_cat (replyBuffer, "Hello World" ); } @end int main ( int argc, char *argv[]) { Hello *hello = [[Hello alloc] initWithBuffer : get_reply (argv)]; [hello whatsup]; [hello free]; return HTTP_200_OK ; // HTTP status code } G-WAN also supports Objective-C++ (with the .mm file extension) and GNUstep, both of which are very popular on Apple computers and mobile devices.

Note that to return an empty reply you should use return HTTP_204_NO_CONTENT; (or exit(204) for CGI scripts) because return 0; ( RC_CLOSE = 0; in gwan.h), or no return code at all, tells G-WAN to gracefully close the connection.

In contrast, return 1; (an [1-99] invalid HTTP code) will prevent G-WAN from generating HTTP headers (which may be handy to return a non-HTTP reply like a raw JSON payload, see RC_NOHEADERS = 1 in gwan.h).

Whatever the language, deploying or updating G-WAN scripts does not require configuration (nor any delay: the latest version is executed on-the-fly). And, as a bonus, Java and C# scripts are served as fast as C scripts by G-WAN, making them fly higher than ever: see these commented benchmark charts comparing G-WAN+Java to Tomcat.

Syntax Errors & Crash Reports

Before running a script, G-WAN reports compilation errors and indicates the offending line(s) in the source code:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Error: hellox.c ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /gwan/0.0.0.0_8080/#0.0.0.0/csp/hellox.c: In function 'main': /csp/hellox.c:7:14: error: 'repl' undeclared (first use in this function) /csp/hellox.c:3:12: warning: unused variable 'reply' 3 | xbuf_t *reply = get_reply(argv); 4 | char *name = 0; 5 | get_arg("name=", &name, argc, argv); 6 | 7 ! xbuf_xcat(repl, "Hello %H", (name && *name) ? name : "you"); 8 | 9 | return HTTP_200_OK; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Identifying the cause of execution errors must be as straightforward as possible. To fix bugs, you just want to know where in your source code the problem happens. Revert to multi-page core dumps only if you have to.

G-WAN execution error reports indicate the offending source code file and line number in the call chain:

Script: crash_libc.c Client: 127.0.0.1 Query : ?crash_libc Signal : 11:Address not mapped to object Signal src : 1:SEGV_MAPERR errno : 0 Thread : 0 Code Pointer: 0000f5200b33 (module:/lib/libc.so.6, function:strcpy, line:0) Access Address: 00000badc0de Registers : EAX=00000badc0de CS=00000033 EIP=0000f5200b33 EFLGS=000000010202 EBX=000000000001 SS=ec2d8ed4 ESP=0000f5ded828 EBP=0000f5dee020 ECX=000033323130 DS=ec2d8ed4 ESI=0000ec2d8f86 FS=00000033 EDX=000003b03c00 ES=ec2d8ed4 EDI=00000badc0de CS=00000033 Module :Function :Line # PgrmCntr(EIP) RetAddress FramePtr(EBP) libc.so.6 : strcpy : - 0000f5200b33 0000ec2d8f00 0000f5dee020 servlet : main : 37 0000ec2d8f00 00000042e10c 0000f5dee020

Servlet crashes do not stop G-WAN. Errors are logged if log files are enabled (useful in daemon mode), and reported on stderr if G-WAN runs in a terminal. Fix the bug and just press [F5] in the Web browser to run the script again.

This makes life easier, allows to write and test code much faster, and makes bug hunting easier than system core dumps.

LIBRARIES

Use databases like IBM DB2 MySQL ORACLE PostgreSQL SQLite, support new output formats like PDF PNG SVG with libcairo, and talk to other SSL FTP IMAP POP3 SMTP LDAP servers with libcurl.

Instead of having to write a new module for each library (like for Apache or Nginx), just use the #pragma link directive in your G-WAN servlets or handlers – there is absolutely no interface code to write:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #pragma link "curl" // link this servlet with the cURL library (no configuration) #include <curl/curl.h> // include cURL definitions #include "gwan.h" // G-WAN API int main ( int argc, char *argv[]) { xbuf_t *reply = get_reply (argv), xbuf; xbuf_init (&xbuf); if ( http_get ( "curl.haxx.se/libcurl/c/" , &xbuf) != CURLE_OK ) xbuf_cat (reply, "Server or resource not available" ); else xbuf_ncat (reply, xbuf.ptr, xbuf.len); xbuf_free (&xbuf); return HTTP_200_OK ; // HTTP status code }

The cURL library alone supports DICT FILE FTP(S) GOPHER HTTP(S) IMAP(S) LDAP POP3(S) RTMP RTSP SCP SFTP SMTP(S) TELNET and TFTP!

If you are short of inspiration then look at /usr/lib . There are thousands of pre-installed libraries ready-to-use from G-WAN, and even more libraries are available from Linux repositories.

HANDLERS

Unlike G-WAN servlets (used to build dynamic contents), G-WAN handlers can also modify the behavior of the server.

This is useful to implement (IP address or content-type) filters, to rewrite client requests, to define how HTTP errors will be processed, or to add custom features – including new network protocols.