Feedback

Frequently Asked Questions

What I find truly baffling are manuals – hundreds of pages long – that accompany software applications, programming languages, and operating systems. Unmistakably, they signal both a contorted design that lacks clear concepts and an intent to hook customers. Niklaus Wirth (1934-2024), "A Plea for Lean Software", 1984 Turing and ACM Awards

  1. How (and Why) G-WAN is different from other HTTP servers?
  2. G-WAN sandboxing + memory-safety, and 2026 Web regulatory requirements
  3. How benchmarks reveal "by-design" weaknesses in all HTTP servers?
  4. What about G-WAN v17's readiness – have you made real-World deployments?
  5. Why are CDNs useful, and how could we do much better, without deploying redundant infrastructure?
  6. Why use G-WAN on Virtual Private Server (VPS) or "Cloud instance"?
  7. How to configure G-WAN's number of concurrent clients?
  8. How to configure G-WAN Hosts, Virtual-Hosts, Aliases and Listeners?
  9. How to configure file/folder permissions?
  10. How to configure custom HTTP error pages?
  11. How to configure DNS (Domain Name Service) & NICs (Network Interface Cards)
  12. Why G-WAN provides a 'ps' process-search command?
  13. How to get the CPU and/or RAM Hogs with G-WAN?
  14. Why G-WAN lists the OS, NICs, CPU/RAM/Disk used and free space?
  15. G-WAN servlets: supported HTTP headers and security-by-design
  16. G-WAN servlets: missing library header
  17. G-WAN servlets: library undefined symbol
  18. G-WAN servlets: using libraries
  19. G-WAN servlets: using libraries from gwan/libraries
  20. G-WAN servlets: installing system-wide libraries
  21. G-WAN handlers: how to trace crashes?
  22. Is G-WAN's source code portable?
  23. Recommended Operating Systems
  24. Hypervisors
  25. Open-Source (License)
  26. Human-readable Crash Reports and Automated Disaster-Recovery
  27. Caching
  28. Changing the PATH environment variable
  29. Setting ENVIRONMENT variables
  30. Why are ENVIRONMENT variables ignored?
  31. Service Mode
  32. Cron Jobs (maintenance)
  33. Support of Programming Languages
  34. Setup of Programming Languages
  35. Questions Not Answered Here

How G-WAN (and Why) is different from other HTTP servers?

δ

I write software since 1979 (at the time in asm). In 2007 I started to think about G-WAN – to save time, money and nerves (other servers were, and still are, too slow, difficult to use, and unsafe). In contrast, G-WAN, first publicly released in 2009, was designed to simplify everything under its reach:

G-WAN provides never-seen-before (in a Web server) detailed system information and features facilitating decision-taking (like for short-term crisis solving, monitoring, audits, or long-term resources provisioning).

Since 2009, G-WAN is faster, safer, more frugal (with disk/CPU/RAM) and easier to use – and it's still making progress:

  At 10,000 concurrent clients (on a 2022 i9 CPU) G-WAN serves MILLIONS of RPS when others serve THOUSANDS of RPS:

(all our 2025 Apache Benchmark (AB) and wrk2 tests are available here)

Year after year, G-WAN has consistently advanced the state of the Art:

  1. G-WAN/no-cache runs at 242m RPS (450+ times higher than NGINX/no-cache, 867x higher than LITESPEED+cache)
  2. G-WAN's startup memory-footprint (usually from 512 KB to 3 MB RSS) grows/shrinks depending on the traffic
  3. G-WAN and servlets are sandboxed in the G-WAN folder at startup (you can ditch RAM/CPU-hungry buggy VMs)
  4. G-WAN has provided "edit & play" servlets in 18 programming languages (sponsors are welcome!)
  5. G-WAN has still no vulnerabilities (unlike APACHE, NGINX, LITESPEED, and almost all other Web servers)
  6. G-WAN works with zero-configuration (relying on adaptive options vs. arcane, proprietary configuration files)
  7. G-WAN and its servlets enjoy "memory-safety" via SLIMalloc (yet another handy, time-saving exclusivity)
  8. G-WAN and its servlets continue unharmed by fatal errors (eg: divison by zero), log useful crash-reports.

We have made a G-WAN binary running under Linux WINE (a Unix Windows implementation) but MICROSOFT "Windows Defender" deletes the G-WAN executable even before it can be copied to disk (if anyone at MICROSOFT reads this, help is most welcome).

We have made a G-WAN binary that should run under Apple's Mac OSX (on AMD64 and ARM CPUs) – but, despite the fact that G-WAN 2009 was written on two MacPro (AMD64) machines, we now lack the recent Apple hardware required to test our ARM code on the latest Mac OSX versions (sponsoring is welcome).

G-WAN 2009 has offered things that nobody else has offered in 2025 (and G-WAN 2025 has added new goodies) like:

  • compliance with the 2026 "memory-safety" regulatory-obligation thanks to SLIMalloc (2020),
  • "edit & play" servlets in 18 programming languages (without a single vulnerability since 2009),
  • 3 orders of magnitude more RPS (Requests Per Second) – at a lower latency – than anyone else for static contents
    (and even higher gains for dynamic contents, like for Web applications, SaaS, AI, IoT telemetry, etc.).

G-WAN offers very desirable features that nobody (despite the trillions of dollars invested) has ever offered. The kind of things that make the difference between economic life and death for most users (if you are not financed, having to switch to Rust is the promise of endless, carefully-designed, sophisticated pains):

  • how useful is it for Web servers to support "memory-unsafe" PHP if international regulations now forbid to deploy it?
  • how usefull are the ever-funded Web leaders if what they do now requires 0.001% of the expenses?

Value is not in the boring, clunky, vulnerable-by-design features that everyone has (via copy & paste).
Value is in the features that everyone needs – and cannot find anywhere.


G-WAN sandboxing + memory-safety, and 2026 Web regulatory requirements

G-WAN stores all its files (websites, logs, etc.) in sub-directories of the location of its executable (the gwan file).

Having it all at the same place makes things much simpler – and much safer since G-WAN then irrevocably jails itself (and any children threads/processes) to:

Since 2009, G-WAN had no vulnerability (both on Windows and Linux), but as an Application server, the OS kernel, servlets and libraries may introduce security issues, see SSL or TLS (which should be a concern for so-called "security layers").

So it makes sense to use every possible way that contributes to exclude uncertainty - including SLIMalloc, which makes G-WAN and all libraries and servlets "memory-safe":

"Memory-safety" is an U.S. regulatory requirement planned for 2026 for all computer programs and programming languages.

Some programming languages claim to be "memory-safe". Yet, even the Rust runtime had memory-safety vulnerabilities. Worse, they all ignore the fact that they invoke operating system features (kernel and usermode) written in C which, without SLIMalloc, are not "memory-safe".

PHP did not expect G-WAN to make it "memory-safe", yet that's the only way for PHP to become compliant (and the same is true for all the other programming languages written in C).


How benchmarks reveal "by-design" weaknesses in all HTTP servers?

δ

Benchmarks let you know how well an application works. In the past, we have been using Weighttp (a good ApacheBench evolution) but things and people have changed, and we now use IBM Apache Benchmark (AB) and NGINX wrk2 because that's what LITESPEED and NGINX insist "is more relevant"... to each of them.

We do this to avoid the cherry-picking done by LITESPEED and NGINX (see below their respective AB/wrk2 tests). Instead, we have accepted both challenges' rules:

  • AB being single-threaded, it cannot saturate the G-WAN multi-threaded server, yet, G-WAN performs better than LITESPEED at this exercise (especially if you take into account the many LITESPEED "failed requests" – see its AB test).
  • wrk2 being multi-threaded, G-WAN serves hundreds of MILLIONS of RPS vs. hundreds of THOUSANDS of RPS for NGINX (nota-bene: NGINX wrote wrk, wrk2 is an slower but more correct version of wrk, read here why).

Logs were disabled for all servers. Caching was enabled for NGINX and LITESPEED (even if G-WAN did not support caching yet at the time of the first tests, hence two series were done for G-WAN, with and without caching). All of our benchmarks are detailed and commented: click each server's dotted link below.

wrk2 TESTS:

G-WAN 17.08.18 (no cache) => [106k - 242m] RPS, [0.7 - 668 MB] RSS, 0 socket errors
  1: 106k RPS
 1k: 1.2m RPS
10k: 242m RPS --> G-WAN peak RPS
20k: 113m RPS
30k:  74m RPS
40k:  53m RPS

G-WAN 17.10.01 (with cache) => [129k - 281m] RPS, [0.7 - 668 MB] RSS, 0 socket errors
  1: 129k RPS
 1k: 1.8m RPS
10k: 281m RPS --> G-WAN peak RPS
20k: 140m RPS
30k:  91m RPS
40k:  63m RPS
--------------------------------------------------------------------------------
LITESPEED Enterprise 6.3.4 (with cache) => [116k - 565k] RPS, [54.8 - 172.7 MB] RSS, 285k socket errors
  1: 116k RPS, Socket errors: read 116
 1k: 565k RPS  --> LITESPEED peak RPS
10k: 279k RPS, Socket errors: timeout 7,451
20k: 220k RPS, Socket errors: timeout 44,312
30k: 201k RPS, Socket errors: timeout 85,010
40k: 180k RPS, Socket errors: timeout 148,176
--------------------------------------------------------------------------------
NGINX 1.24.0 (with cache) => [89k - 944k] RPS, [130.9 - 143.8 MB] RSS, 29k socket errors, 648 non-2xx responses
  1:  89k RPS
 1k: 944k RPS --> NGINX peak RPS
10k: 635k RPS
20k: 561k RPS, Non-2xx or 3xx responses: 8
30k: 489k RPS, Non-2xx or 3xx responses: 29
40k: 474k RPS, Non-2xx or 3xx responses: 611, Socket errors: timeout 29040
================================================================================
First 2025 tests without caching (used by the "G-WAN vs NGINX" bar chart):
--------------------------------------------------------------------------------
G-WAN 17.04.04 (no-cache) => [58m - 242m] RPS, 0 socket errors
10k: 242m RPS
20k: 120m RPS
30k:  76m RPS
40k:  58m RPS
--------------------------------------------------------------------------------
NGINX 1.24.0 (no-cache) => [343k - 555k] RPS, 207k socket errors
10k: 555k RPS, timeouts: 5,358
20k: 441k RPS, timeouts: 22,539
30k: 371k RPS, timeouts: 62,312
40k: 343k RPS, timeouts: 117,097

G-WAN delivers MILLIONS of RPS (without error) instead of THOUSANDS of RPS with many errors (for LITESPEED and NGINX).
So, even if you can tune an OS or a server to run it twice faster, the results are the same: G-WAN is faster by 3 orders of magnitude.

AB TESTS:

G-WAN 17.08.18 (no cache)          => 111k RPS,  0.7 MB RSS,   0 failed requests
G-WAN 17.10.01 (/w cache)          => 137k RPS,  0.7 MB RSS,   0 failed requests
LITESPEED Enterprise 6.3.4 (/w cache) => 121k RPS, 54.8 MB RSS,  99 failed requests
NGINX 1.24.0 (/w cache)             => 92k RPS, 130.9 MB RSS,   0 failed requests

Unlike wrk2, AB is not multi-threaded – hence its inability to extract decent concurrency from the servers. To prove this, and to make sure that AB's reported "failed requests" count was a fair report for LITESPEED (and not just an isolated glitch), we have made half a dozen AB tests (with an increasing number of connections) for LITESPEED. All AB results are better than wrk2 – for LITESPEED only, and most LITESPEED AB/wrk2 tests have similar errors (click on the above link to see them).

The reason why LITESPEED prefers AB comes from its small initial server setup. On our 32-Core CPU, LITESPEED runs 2 worker processes of 6 threads each – as compared to NGINX (32 worker processes of 1 thread each).

  • Less workers (either threads or processes) give better results with low concurrencies (less scheduling overhead).
  • More workers (either threads or processes) give better results with high concurrencies (due to the need for scheduling).

NGINX and LITESPEED start with a configured number of workers. G-WAN starts small and grows/shrinks on-demand.
G-WAN's adaptive way is more difficult to do right – but it scales and performs much better.


What about G-WAN v17's readiness – have you made real-World deployments?

This new codebase (a complete rewrite) has been used in production since 2024, for different Web applications (each deployed on many fixed sites and mobile platforms) such as:

  • for an international network of schools – generating PDF questionnaires on-demand from a SQL database of Q & A, collecting online scanned student test answers, checking the good/bad answers to generate PDF reports for each student and for aggregated notes – per classroom, per teacher, secured by custom vectorial QR-Codes embedded in PDF files (410 pages analyzed by second on one single 2008 CPU Core, with English and UNICODE text in different alphabets).
  • for a network of warehouses, distributors and traveling vendors – a distributed SQL Web application used by many vendors, distributors and resellers, and point-of-sale vendors with thousands of products made of other tens of thousands of sub-products, packaging, pricing schemes, various volume/weight/casing units and language conversions, custom searches, filters, and validations for reporting – all synchronized even when connectivity was intermittent or lacking (mobile users, global coverage in many countries).
  • for a company migrating from MICROSOFT Excel to online SQL databases – a real-time MICROSOFT Excel import-to-SQL and export-from-SQL platform, supporting MS-Excel data, styles, formulas, input validations, with the detection and automatic correction user-input errors and inconsistencies (eg: gazillions of references were fat-fingered or left blank, and a same product was sold under many different descriptions, under different packagings and sometimes invalid pricing and units – invariably leading to deadly SQL foreign key violations).

This was a great (sometimes challenging) way to exercise our G-WAN SQL API (wrappers for the SQLite API that let programmers only use 3 C functions safely handling every possible SQL requests while getting the results in JSON/CSV/XML/TEXT/HTML and other formats). Many of these SQL requests had more than 100 lines, some had more than 500 lines. Saving time starts with making complex things much simpler (and faster, here with in-memory, automatically synchronized, SQLite tables).

We also had to push things further with the Linux OS to load humongous third-party shared libraries (supporting the MS-Excel file format implies to deal with its many versioned incompatibilities) from the G-WAN static executable, and to make all this work without hitting the walls of the G-WAN sandbox.

G-WAN exists since 2009. And it evolves, the good way, as time goes: ever-faster, safer, more capable, flexible and scalable – yet ever-easier to use (because we use it daily).


Why are CDNs useful, and how could we do much better, without deploying redundant infrastructure?

δ

Short answer: G-WAN.COM is 1 small (4-Core, 32 GB, 1 Gbps) server hosted at 1 single physical place, while GOOGLE.COM relies on a worldwide distributed architecture of millions of hardware servers – a global CDN (Contents Delivery Network) enjoying its own (high-bandwidth, low-latency) trans-oceanic optical-fibers (independent from public networks).

A CDN (many servers) can better handle traffic peaks than a single server – especially if the single HTTP server has to defend itself against DDoS (Distributed Denials of Service) attacks with small timeouts (that is, the obligation to cut idle connections early because many nefarious clients try to overwhelm the server with idle connections... a situation that exists only when a server has the obligation to accept all the connections from all the clients).

Networks are improving, but (due to their topology) they are still dominated by latencies: independently from the speed of the client and server Internet access, networks are made of routers/gateways that introduce latencies (that is, the time taken by each intermediary router/gateway to process network packets).

A typical Internet link has 10-15 hops. Reducing the hops reduces the latencies – hence the CDNs using many servers worldwide (to reduce the physical distance, and therefore the hops, between clients and servers).

CDNs being made of redundant infrastructure, they are very expensive (to deploy and operate), and are therefore reserved to the very rich (when CDN capacity is free, you are obviously the product: someone has to pay for this infrastructure, and the CDN operator sells their capacity to spy, sabotage or stop anyone using its services). Finance is obsessed by control (hence the recurring resurrection of projects like TIA, which stands for "Total Information Awareness").

This poor network design (introduced to monitor and control all the traffic) would be gone with point-to-point networks. Without intermediary routers/gateways, the only limitation would be raw bandwidth – which can easily be parallelized (by slightly varying the transmission speed) to achieve never-seen-before performance – unhampered by hop-latencies.

Benchmarks made on the Internet test the (in this order of importance as bottlenecks):

  1. client Internet access (bandwidth and latency)
  2. server DNS (CDN load-balancing to pick the server closest to the client)
  3. server Internet access (bandwidth and latency)
  4. client LAN (switches, gateways, firewalls, routers)
  5. client hardware (CPU, RAM, NIC)
  6. server LAN (switches, cache servers, reverse proxies, load-balancers, gateways, firewalls, routers)
  7. server hardware (CPU, RAM, NIC)
  8. server software (OS like Linux, HTTP server like G-WAN)

As you can see, G-WAN comes last in the delivery chain. So if you think that throwing wrk2 to gwan.com actually tests the G-WAN software then you are wrong (at best you are testing G-WAN timeouts, which are necessarily small to defend against constant attacks since 2009).

All you are doing is testing every single potential bottleneck of the above list BEFORE reaching G-WAN. That's why making comparative wrk2 benchmarks on localhost (and with very high timeouts) is the only way to get results that make sense: you test the G-WAN software against NGINX or LITESPEED, instead of comparing 1 machine to a distributed, redundant, load-balanced harware infrastructure costing hundreds of billion dollars.


Why use G-WAN on Virtual Private Server (VPS) or "Cloud instance"?

δ

Virtualized servers mutualize access to CPU and RAM resources – with an overhead (while injecting more vulnerabilities than already available in the OS) – but we will see that there's much, much worse (than CPU caches trashing and spiraling TLBs).

You can deploy many G-WAN instances on a machine because they are isolated from each other (G-WAN and its servlets cannot reach files outside of each instance's directory). As a result, the VMs (their vulnerabilities and CPU/RAM overheads) are redundant.

But no hosting company deploys G-WAN (yet), so, currently, the situation is a follows:

It's obvious that "Dedicated virtual CPU Cores" or "Cloud instances" split a machine CPU and RAM between customers. But the hosting companies don't tell you that tens (or hundreds) of users are also sharing one single NIC and disk.

A shared disk or NIC will quickly become THE bottleneck (slowing-down everyone, because, hey, a virtual machine is not a new machine, it's merely real-estate time-sharing – and the some "co-renters" may want to enjoy 10 to 100% of the disk or NIC).

What can you do if a dozen of happy campers occupy the bathroom for a few hours?
There is no (enjoyable) room left for anyone else.

Even if users are not aiming to exhaust physical disk and network resources – their sheer number will do it. And, as it happened to me, I can tell that the hosting company does not care about your problems: from their point of view, you have signed a contract and they want you to pay for the thing they have explicitely called "virtual" or "cloud" (which, in reality, means "shared").

Their could (and technically should) dedicate a disk and NIC to every customer, but that's raising their operating costs (in hardware, maintenance and electricity), so they don't do it.

Parcimonious programs, like G-WAN (which is both parcimonious and much faster than other servers), can help: let's compare the G-WAN memory footprint (that will grow and shrink on-demand):

 > ./gwan -p
- running gwan process(es):

    PID  THRDS  %CPU    VIRT      RSS   SHRD  EXE
 537230     17   0.0  6.9 MB  768.0 KB   0.0 KB  /opt/gwan/gwan :8080

...to the (fixed, declared in configuration files) NGINX memory footprint:

./gwan -p ng
- running nginx process(es):

    PID  THRDS  %CPU     VIRT    RSS      SHRD  EXE
   2575      1   0.0  20.9 MB  1.8 MB    1.0 MB  nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
   2576      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2577      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2578      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2579      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2580      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2581      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2582      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2583      1   0.0  22.9 MB  3.8 MB    2.5 MB  nginx: worker process
   2584      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2585      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2586      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2588      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2589      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2590      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2591      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2592      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2593      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2594      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2595      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2596      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2597      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2598      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2599      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2600      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2601      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2602      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2603      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2604      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2605      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2606      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2607      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2608      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   Total: 1.8 + (31 * 4) + 3.8 + 2.7 = 132.3 MB

G-WAN serves many more simultaneous clients with much less RAM than APACHE, LITESPEED or NGINX (and G-WAN does so without any configuration nor humongous amounts of pre-allocated memory).


How to configure G-WAN's number of concurrent clients?

δ

Unlike other Web servers like APACHE, LITESPEED or NGINX (and Application servers like GlassFish or Tomcat), G-WAN does not use configuration files: the values are adjusted on-the-fly depending on the current traffic.

In APACHE, LITESPEED or NGINX, the number of concurrent clients must be hard-coded in configuration files because they reserve the corresponding amount of memory at startup, before listening and accepting connections.

The NGINX default memory footprint (for a 32-Core CPU) is 132.3 MB, as shown in the previous Q&A.

The fixed memory footprint for "LITESPEED Enterprise" consumes 54.8 MB RAM at startup (changing the "LITESPEED Enterprise" number of worker processes is "Only Available For Web Host Elite Licenses"):

./gwan -p lite
- running litespeed process(es):

   PID  PPID THRDS  %CPU     VIRT     RSS    SHRD  EXE
 11474  1791     1   0.0  38.7 MB  17.5 MB  1.5 MB  litespeed (lshttpd - main)
 11478 11474     6   0.0  80.4 MB  17.9 MB  1.5 MB  litespeed (lshttpd - #01)
 11479 11474     6   0.0  80.4 MB  17.9 MB  1.5 MB  litespeed (lshttpd - #02)
 Total: 17.5 + (2 * 17.9) + 1.5 = 54.8 MB

In contrast, G-WAN starts with a 768 KB (70x lower than LITESPEED, and 172 times lower than NGINX) memory footprint because G-WAN allocates memory on-demand rather than upfront.

And load tests show that under heavy loads G-WAN's memory consumption will grow far slower than for the APACHE, LITESPEED and NGINX servers... while G-WAN is serving 3 orders of magnitude more requests per second (millions instead of thousands)!

This matters: while G-WAN will not be overwhelmed by a traffic spike, APACHE, LITESPEED and NGINX will stop responding – either because the fixed option has been setup at a low value to save RAM, or because the server's scalability limit has been reached (yes, all hardware and software servers have a concurrency limit).

But configuration files and fixed values also raise problems for usability, performance and security: you don't want to see your server down when your company is finally successful (or because it is under attack... probably for the same reason).

By using adaptive variables instead of the configuration files' fixed values, the zero-configuration G-WAN server not only makes it easier for users to deploy server and applications (there's less room for errors and the learning curve is much smaller) but it also makes G-WAN both more efficient and safer.


How to configure G-WAN Hosts, Virtual-Hosts, Aliases and Listeners?

δ

Since 2009, Websites, Listeners and Hosts are defined by creating G-WAN sub-folder names. G-WAN v17+ (2025+) has pushed this logic further (things are even simpler now).


The Default www Website

This is where the client requests missing a "Host: " HTTP header will land.

  • Clients will be unable to fetch any file or folder located outside of www.
  • Clients will be unable to fetch any file or folder located inside www, if their name starts with a dot (the '.' character).

The starting dot restriction allows servlets (like '/?file=12345') to protect the access to static files that you want to market (works, music, videos, etc.) with a password and/or a NAMED IPv4 whitelist (like 'client123', 'admin', 'private', 'level5', etc.)... but you can also store there your own files (libraries, databases, configuration files, etc.).

Since G-WAN's throughtput (on a Core i9 CPU) is greater than 1 Tbps G-WAN will transparently use all the available NICs (able to reach the clients). For fail-safety and load-balancing, the NICs can be connected to different networks.



  • Multi-homing: using 1 machine to host several websites. With virtual-hosts this can be done with 1 or several IP addresses.
  • Virtual-hosts: using 1 server machine and 1 G-WAN process to serve different websites, with 1 single IP address if you wish.
  • Host-Aliases: serving the same contents for several domain-names (like gwan.ch and gwan.com).


1. For VIRTUAL-HOSTS, create sub-directories of the gwan executable location:

Here is an example:

 mkdir www               # website 1  ("www" is the default site)
 mkdir $admin.gwan.com    # website 2               (virtual-host)
 mkdir $forum.gwan.com    # website 3               (virtual-host)

To use an ALIAS add a symbolic link ($gwan.ch points to www):

 ln -s www $gwan.ch    # OR: ln -s www '\$gwan.ch'

Note: ln -s www $gwan.ch is more intuitive when it works, but some Linux distributions use the $ character to lookup the gwan environment variable (even if no such variable exists) – creating a .ch link instead of the expected $gwan.ch. That's why you may have to use escaping, and type: ln -s www '\$gwan.ch'

With only one running ./gwan program, the directory structure will be (that's an example, it can be anywhere outside /opt):

 /opt/gwan ................... gwan program location
 /opt/gwan/www .............. website 1             (default website)
 /opt/gwan/$gwan.ch .......... alias to website 1    (symlink to www)
 /opt/gwan/$admin ............ website 2             (virtual-host)
 /opt/gwan/$support ........... website 3             (virtual-host)

Website visitors will reach these websites like this (here all with the same default port):

 http://www.gwan.com ......... website 1
 http://www.gwan.ch .......... website 1 (alias)
 http://admin.gwan.com ....... website 2 (virtual host)
 http://forum.gwan.com ....... website 3 (virtual host)

2. VIRTUAL-HOSTS using several IP addresses (network interfaces multi-homing)

If you let G-WAN listen on 0.0.0.0 (all interfaces, the default option when you run ./gwan) then 1 single gwan program will be able to serve VIRTUAL-HOSTS that point to DIFFERENT IP ADDRESSES (the ones tied to your network interfaces).

The setup is exactly the same as above (for virtual-hosts listening on 1 single IP address). You have nothing else to do except to configure the network interfaces (see the DNS section below in this page).


3. Without virtual-hosts, each website needs 1+ IP address and 1 G-WAN process:


 /opt/websites/site .......... gwan program location (./gwan gwan.com:80)
 /opt/websites/site/www ...... website 1 (reachable by listener's IP:port)

 /opt/websites/admin ......... gwan program location (./gwan admin.gwan.com:81)
 /opt/websites/admin/www ..... website 2 (reachable by listener's IP:port)

A single IP address can be shared by several websites by listening on different port numbers, but this is not practical for website visitors (they must specify the port number at the end of the Web address):

 http://www.gwan.com ......... website 1 (port 80, default Web port number)
 http://admin.gwan.com:81 .... website 2 (port 81)

So, most of the time, you will prefer to dedicate 1 IP address by site.

Running many G-WAN processes allocates redundant CPU and RAM resources, in different directories, leading to less efficiency than 1 single G-WAN instance serving with VIRTUAL-HOSTS.

Yet, since each G-WAN is so frugal and sandboxed, there are cases (like for better isolation and observability) when you may prefer to run many instances instead of one.


Conclusion:

G-WAN virtual-hosts simplify server deployments, their maintenance and administration, on the top of saving CPU and RAM.

Virtual-hosts and Aliases can even be added while G-WAN is running: the virtual-hosts files are served as soon as they are available (you don't have to edit configuration files and then restart G-WAN).

The $ prefix character groups G-WAN virtual-hosts and aliases, when listed from a terminal (or Desktop file-manager):

 $ ll
 drwxrwxr-x  '$admin.gwan.com'/
 drwxrwxr-x  '$forum.gwan.com'/
 drwxrwxr-x  '$support.gwan.com'/
 lrwxrwxrwx  '$gwan.ch' -> www/
 ...
 drwxrwxr-x  www/

To list only virtual-hosts and aliases (with their contents!) do this:

 $ ll \$*
 lrwxrwxrwx  '$gwan.ch' -> www/

 '$admin.gwan.com':
 -rw-rw-r--  index.html

 '$forum.gwan.com':
 -rw-rw-r--  index.html
 -rw-rw-r--  index.html.gz

 '$support.gwan.com':
 -rw-rw-r--  .404.html
 -rw-rw-r--  index.html

Note: G-WAN supports TLS SNI (Server Name Indication) which allows to get the virtual-host name (in plaintext) before TLS handshakes are done in order to use the domain-matching certificate. As a result, the G-WAN virtual-hosts feature works for HTTPS like for HTTP.


How to configure file/folder permissions?

In any website directory, an index.html file is either:

  • a website page (with user-defined contents),
  • a "403 Forbidden" page (when no directory-listing is desired),
  • a directory-listing page (with sortable name/date/size columns).

Depending on the index.html presence/absence, G-WAN behavior is (there's no 3xx redirection):

 curl -v "127.0.0.1:8080/imgs"  => 200:index.html or 403:no index.html
 curl -v "127.0.0.1:8080/imgs/" => 200:index.html or 403:no index.html

By default, directory-listing is disabled. So, by allowing directory-listing or by copying an index.html file, you can decide on a per-folder basis of what is visible to all (or whitelisted) clients.


How to configure folder aliases to avoid redirections?

Background: many HTTP servers need an explict ending / character to serve folder contents: servername.com/directory/ will fetch the desired content, but servername.com/directory will return a 404 "file not found" error.

The authors of these HTTP servers explain that their server must send a 3xx redirection to the client asking it to add the trailing slash, because, they state, wihtout this character ending an URL, "relative URLs would not work properly".

When G-WAN receives an URL, it checks if that's a file or a folder. And, if this is a folder, G-WAN adds the ending / so that the client does not have to be instructed (with a 3xx redirection) to send the "correct" URL.

As a consequence, with G-WAN, there's no need to define directory aliases missing the ending / to avoid the redirection.

How to configure custom HTTP error pages?

If they are not yet present, G-WAN creates default error pages at startup. These files are named like .404.html (the file name starting dot prevents G-WAN from serving the file when queried by clients) located in the root folder of each host (so www for the default website, and something like $gwan.com for virtual hosts).

To use your own HTTP error pages, just copy them in the root folder of each host (no further configuration is required).

Most status codes (in the 100-399 range) are never seen by humans and therefore rather use a tiny G-WAN design to deliver more speed and save bandwidth.

Only some of the 4xx and 5xx status codes (400, 403, 404, 405, 416 and 500) deserve a pretty body:

100-199 ... Informational responses  |
200-299 ... Successful responses     | G-WAN tiny design
300-399 ... Redirection messages     | 
--------------------------------------
400-499 ... Client error responses   | These ranges can use larger,
500-599 ... Server error responses   | more elegant, designs

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
https://httpwg.org/specs/rfc9110.html#overview.of.status.codes


How to configure DNS (Domain Name Service) & NICs (Network Interface Cards)

(it's not specific to G-WAN, but having this information at hand is handy)

That's how domain-names, DNS, and NICs can be configured:

RFC 7235 defines a FQDN (Fully Qualified Domain Name) as: hostname.domain.tld (like www.gwan.com)

- Host      Name        : "www"=website, "smtp/pop3/imap"=email-server
- Domain    Name        : "gwan" in "www.gwan.com" is the org/network
- Top-Level Domain (TLD): ".com/.org/.net"         is the type/purpose

ISPs and small-businesses use multi-homing to generate custom web addresses:

- www.domain.tld
- admin.domain.tld
- forum.domain.tld, etc.

1. Your hostnames may point to 1 single IP address (using DNS CNAME aliases):


 www.domain.tld    IN       A  12.34.56.78
 admin.domain.tld  IN  CNAME  www.domain.tld
 forum.domain.tld  IN  CNAME  www.domain.tld

A wildcard DNS record instead of CNAME may look like a clever shortcut. But, by doing so, you let people link to your website with any sub-domain of their choice, like: https://i.dont.like.this.domain.tld (which is probably not what you want).

Yet, many people do this, so, to prevent these sneaky attacks, G-WAN does not redirect sub-domain requests to their canonical address (http://www.domain.tld) with an HTTP 301 redirection like most other servers do (people will visit the defautl www website which usually just contains a 'welcome' page). As an extra bonus, this G-WAN behavior spares pointless traffic.

DNS wildcards also cause many problems with SPF, DMARK, etc. and are massively abused by Spammers. You don't want that. Keep things simple and predictable.


2. But hostnames may also point to different IP address (using DNS "A" records):


 www.domain.tld    IN  A  12.34.56.78
 admin.domain.tld  IN  A  12.34.56.79
 forum.domain.tld  IN  A  12.34.56.80

With several IP addresses, if you want to let users reach your websites not only by domain-name (http://domain.tld) but also by IP-address (http://12.34.56.80) then create symbolic links to directories:

 ln -s $www.domain.tld 12.34.56.78
 ln -s $admin.domain.tld 12.34.56.79
 ln -s $forum.domain.tld 12.34.56.80

3. In both cases, your have to attach your IP address(es) to the NIC(s) of your server machine (here 1 IP address is used on 1 NIC):


 ifconfig eno1 www.domain.tld
 ifconfig eno1 admin.domain.tld alias
 ifconfig eno1 forum.domain.tld alias

DNS Records Reference List:

 A     : IPv4 address of the hostname
 AAAA  : IPv6 address of the hostname
 CNAME : alias, points the sub-domain to its domain (www.gwan.com to gwan.com)
 MX    : email server address, mail servers priority
 NS    : authoritative nameservers of a domain (DNS server address)
 PTR   : reverse IP lookup (map an IP-address to a domain-name)
 SRV   : location and configuration of a particular service (email, VoIP...)
 SOA   : Start Of Authority, information about the DNS zone
 TXT   : configuration of SPF, DKIM, or DMARC records.
 CAA   : SSL/TLS / which authorities can issue certificates for a domain
 DS    : Delegation Signer, chain of trust between the parent/child zones
 DNSKEY: public signing keys like Zone Signing Key (ZSK)/Key Signing Key (KSK)


Why G-WAN provides a 'ps' process-search command?

  1. 'ps' consumes too much CPU time and RAM to be invoked by G-WAN as a child process;
  2. 'ps' reports memory quantities in kilobytes – without pretty thousands (readability matters);
  3. 'ps' has a complex syntax – that evolves as time goes (features' availability matters);
  4. 'ps' does not report (yet) the SHARED memory of a process (it matters too);
  5. 'ps -C' needs you to know the exact, full process NAME to find matches;
  6. 'ps o pid,exe -C dbus' needs sudo to return a PATHNAME, not 'gwan -p dbus';
  7. G-WAN needs to watch its siblings, children and its environment;
  8. G-WAN handlers and servlets can now use a fast, reliable 'ps' feature;
  9. G-WAN can also search ABBREVIATED process NAMES (that may be very handy):
./gwan -p gvfsd
- running 'gvfsd[*]' process(es):

  PID  PPID  THRDS  %CPU      VIRT      RSS    SHRD  EXE
 1992  1836      4   0.0  312.4 MB   7.2 MB  6.5 MB  /usr/libexec/gvfsd
 2010  1836      7   0.0  454.3 MB   6.0 MB  5.7 MB  /usr/libexec/gvfsd-fuse
 2466  1992      5   0.0  528.6 MB   7.2 MB  6.7 MB  /usr/libexec/gvfsd-trash
 3714  1992      5   0.0  457.0 MB   7.7 MB  7.2 MB  /usr/libexec/gvfsd-network
 3731  1992      4   0.0  386.8 MB   8.2 MB  7.5 MB  /usr/libexec/gvfsd-dnssd

A shorter prefix leads to a wider search (and still relevant results in this case):

./gwan -p gv
- running 'gv[*]' process(es):

  PID  PPID  THRDS  %CPU      VIRT      RSS    SHRD  EXE
 1992  1836      4   0.0  312.4 MB   7.2 MB  6.5 MB  /usr/libexec/gvfsd
 2010  1836      7   0.0  454.3 MB   6.0 MB  5.7 MB  /usr/libexec/gvfsd-fuse
 2132  1836      5   0.0  457.9 MB  10.2 MB  8.7 MB  /usr/libexec/gvfs-udisks2-volume-monitor
 2154  1836      4   0.0  308.0 MB   6.2 MB  5.7 MB  /usr/libexec/gvfs-mtp-volume- monitor
 2159  1836      5   0.0  385.7 MB   7.2 MB  6.5 MB  /usr/libexec/gvfs-afc-volume-monitor
 2179  1836      4   0.0  307.9 MB   5.7 MB  5.5 MB  /usr/libexec/gvfs-goa-volume-monitor
 2209  1836      4   0.0  309.0 MB   6.7 MB  6.0 MB  /usr/libexec/gvfs-gphoto2-volume-monitor
 2466  1992      5   0.0  528.6 MB   7.2 MB  6.7 MB  /usr/libexec/gvfsd-trash
 3714  1992      5   0.0  457.0 MB   7.7 MB  7.2 MB  /usr/libexec/gvfsd-network
 3731  1992      4   0.0  386.8 MB   8.2 MB  7.5 MB  /usr/libexec/gvfsd-dnssd


How to get the CPU and/or RAM Hogs with G-WAN?

There are times when you need to find where all that CPU and/or RAM is used. Linux provides commands, which, when combined, allow to do this, but the complex syntax is hard to remember and therefore difficult to type quicky without errors when you need it.

Further, G-WAN provides more information (like the SHARED memory), in human readable form (KB, MB, GB), and in a more accurate way (some executables override their executable path information with other information, making it more difficult to find their path). Last but not least, G-WAN does it much faster than ps – and it is available from the command-line or from a servlet (here on a Desktop machine):

./gwan -pc
- CPU hogs (top-10):

   PID    PPID  THRDS  %CPU       VIRT      RSS      SHRD  EXE
 50145    4348     42     3.1    3.8 GB  105.1 MB   67.5 MB  /usr/bin/vlc
  2703    2655     51     2.5    6.7 GB  255.2 MB  114.8 MB  /usr/bin/cinnamon
 49837    2703    101     2.4    4.4 GB  421.6 MB  223.4 MB  /home/elisa/Downloads/firefox/firefox-bin
  2278    1932      8     1.0    1.3 GB  245.6 MB  173.1 MB  /usr/lib/xorg/Xorg
 49960   49917     28     0.4    3.4 GB  145.5 MB  105.8 MB  /home/elisa/Downloads/firefox/firefox-bin
  2323    2308      3     0.3  131.3 MB   28.2 MB   10.7 MB  /usr/bin/pipewire
  2320    2308      3     0.3  122.7 MB   18.1 MB   10.4 MB  /usr/bin/pipewire
  4348    2703      6     0.2    1.4 GB  105.8 MB   53.7 MB  /usr/bin/nemo
 18169    2308      6     0.1  735.8 MB   74.7 MB   49.5 MB  /usr/bin/zedit
   270       2      1     0.1    0.0 KB    0.0 KB    0.0 KB  kworker/u65:0+i915_flipcation-service

Above that is for CPU Hogs, and below this is for RAM Hogs:

./gwan -pr
- RAM hogs (top-10):

   PID    PPID  THRDS   %CPU      VIRT      RSS      SHRD  EXE
 49837    2703    101    2.4    4.4 GB  421.6 MB  223.4 MB  /home/elisa/Downloads/firefox/firefox-bin
  2703    2655     51    2.5    6.7 GB  255.2 MB  114.8 MB  /usr/bin/cinnamon
  2278    1932      8    1.0    1.3 GB  245.6 MB  173.1 MB  /usr/lib/xorg/Xorg
  2745    2324     12    0.0    1.4 GB  225.3 MB   93.1 MB  /usr/bin/gnome-software
 17822    2752      7    0.0    3.2 GB  205.3 MB  132.0 MB  /usr/bin/evince
 50042   49917     20    0.0    3.4 GB  171.7 MB  118.0 MB  /home/elisa/Downloads/firefox/firefox-bin
  3007       1      6    0.0  606.0 MB  168.9 MB   35.5 MB  /usr/libexec/fwupd/fwupd
 49960   49917     28    0.4    3.4 GB  145.5 MB  105.8 MB  /home/elisa/Downloads/firefox/firefox-bin
  4348    2703      6    0.2    1.4 GB  105.8 MB   53.7 MB  /usr/bin/nemo
 50145    4348     42    3.0    3.8 GB  105.1 MB   67.5 MB  /usr/bin/vlc


Why G-WAN lists the OS, NICs, CPU/RAM/Disk used and free space?

Because having all this information in one place is very useful (sparing you the hurdle of using tens of commands with various names, availabilities, incompatibilities and cabalistic syntaxes – because every Linux distribution "knows better"):

$ ./gwan :8080
G-WAN App. Server v17.01.18 with "memory-safe" (SLIMalloc) C servlets
─────────────────────────────────────────────────────────────────────
⧉ servlets      : G-WAN servlets examples
─────────────────────────────────────────────────────────────────────
- host OS        : Ubuntu 24.04 LTS
- host domain    : (not set)
- host name      : IBM-14
- pid, ppid      : 13982 (12987:bash)
- backlog        : 4,096
- ports range    : 1,025-65,535 (allowed:64,510 on 65,535)
- max sockets    : 1,048,576 (soft:1,024 hard:1,048,576)
- CPU model      : 13th Gen Intel(R) Core(TM) i9-13900K
- CPU cores      : 32 online (as setup by BIOS/OS/VM)
- CPU freq (GHz) : seen[0.800-2.300] capable[0.8-5.8]
- CPU power      : powersave, balance_performance
- CPU load (avg) :   0% 
/ 1 minute - RAM used : 3%
5/188 GB - Disk used : 23%
229/996 GB - network card : en0 192.168.21.142 255.255.255.0 00:13:3b:99:72:81 - network card : en1 123.234.45.105 255.255.255.0 00:13:3b:99:45:63 - listening on : http://192.168.21.142:8080 - listening on : http://123.234.45.105:8080 - hosts to serve : hosts:255, aliases:128, errors:0 (files:143,059, 2.5 GB) - worker threads : 16 (0.50 / cpu core)

It helps to setup/upgrade systems or to check their current state (helping you to notice broken disks, NICs or RAM modules).
The G-WAN 'status' page (available via servlets and ./gwan -r) lists much more information:

- host name ........  IBM-14
- host IP addr .....  192.168.21.142, 123.234.45.105
- host domain ......  (not set)
- host UTC time ....  Wed, 03 Sep 2025 04:48:25 GMT
- host OS ..........  Ubuntu 24.04 LTS
- host processes ...  988

- gwan version .....  17.08.26 (2025)
- gwan pid, ppid ...  1936 (1935:bash)
- gwan hosts .......  hosts:255, aliases:128, errors:0, files:143,059, 2.5 GB
- gwan UTC start ...  2025.09.03 03:35:42
- gwan uptime ......  01:12:43
- gwan signals .....  0 (from servlets)
- gwan forks .......  0 (start: 2025.09.03 03:35:42)

- gwan VIRT memory .  7.1 MB
- gwan RSS .........  1.2 MB
- gwan RSS peak ....  1.9 MB
- gwan PG reclaims .  4.4 GB

- gwan traffic total  IN:2.2 GB, OUT:6.4 GB
- gwan traffic daily  IN:2.2 GB, OUT:6.4 GB
- gwan traffic today  IN:0.618 KB, OUT:34.7 KB
- clients current ..  2 (14 idle / 16 workers, peak: 5)
- clients accepted .  21 (0 whitelisted)
- clients rejected .  0 (0.0% of total)
- http requests ....  21,000,056 (files:21,000,053, servlets:3)
- http req/accept ..  1,000,002.67
- http req/day .....  21,000,056 (today:21,000,056, per-second:75,732)
- http codes .......  1xx:0 2xx:21,000,055 3xx:0 4xx:0 5xx:0
- http errors ......  http:0 vers:0 cut:0 bad:0
- tcp  i/o errors ..  acpt:0 tmo:15 rst:0

- gwan avg CPU load    3% 
- system ⎫ 1 min 1%
CPU load ⎬ 5 min 0%
average ⎭ 15 min 0%
- system RAM (used) 8%
14/188 GB - system Disk (used) 23%
244/996 GB - CPU model ........ 13th Gen Intel(R) Core(TM) i9-13900K - CPU cores ........ 32 online - CPU freq (GHz) ... seen[0.800-2.300] capable[0.8-5.8] - CPU power ........ powersave, balance_performance - NICs ............. 1 en0 192.168.21.142 255.255.255.0 00:13:3b:99:72:81 RX:0.7 GB, TX:12.7 GB en1 123.234.45.105 255.255.255.0 00:13:3b:99:45:63 RX:1.5 GB, TX:14.3 GB - request time ..... 72 µs [27-113] - log file ......... 15.9 MB

As a runtime-switchable option, you can even have a scrollable log file's tail on a second column (on the right, not shown here). That's very useful while writing Web Apps, or when monitoring a server (either remotely or locally, from a Web browser or from the command-line – you have the choice!).

The ability to compare a specific G-WAN instance CPU load to the system's total CPU load – or the total (not only HTTP) incoming traffic to the total outgoing traffic, is crucial to detect abnormal situations requiring further investigations.

You can get this (CPU and total traffic) information from an HTTP request to a servlet or from the command-line with ./gwan -r (as listed above) or with the more focused ./gwan -p and ./gwan -n command-line (listed below):

./gwan -p
- running gwan process(es):

  PID  THRDS   %CPU      VIRT       RSS      SHRD  EXE
 6938     17    4.7    7.1 MB    1.2 MB    0.0 KB  /opt/gwan/test0/gwan :8080
 7366     17    0.0    4.3 MB  768.0 KB    0.0 KB  /opt/gwan/test1/gwan :8081
 7401     17    0.0    4.3 MB  512.0 KB    0.0 KB  /opt/gwan/test2/gwan :8082

Network cards:

./gwan -n
- available network interfaces:

  en0 192.168.21.142 255.255.255.0 00:13:3b:99:72:81  RX:0.7 GB, TX:12.7 GB
  en1 123.234.45.105 255.255.255.0 00:13:3b:99:45:63  RX:1.5 GB, TX:14.3 GB

Generally, HTTP server 'status' pages are not as complete as G-WAN's (and rarely readable from the command-line), and third-party monitoring tools are not as focused (providing information that we don't need, and missing the data we need).

This is why G-WAN does it all (while consuming as little CPU/RAM resources as possible, and without injecting gratuitous complications, incompatibilities and... new vulnerabilities).


G-WAN servlets: supported HTTP headers and security-by-design

Since 2009, many new standard HTTP headers have been added by the industry – even to HTTP/1.1. Some are unusually verbose, making HTTP/2-3's HTTP headers compression find a purpose: we got "DNT: 1" for "Do-Not-Track", but the much longer "Upgrade-Insecure-Requests: 1" was not shortened. It makes you wonder what these committees are drinking.

To make room for trackers and botnets acting under the disguise of offering (gratis) Web services, a passion to cancel decades-old, by-default security has also surfaced (again, without leveraging the established "ACL" technical abbreviation):

  1. "Access-Control-Allow-Credentials"
  2. "Access-Control-Allow-Headers"
  3. "Access-Control-Allow-Methods"
  4. "Access-Control-Allow-Origin"
  5. "Access-Control-MaxAge"
  6. "Access-Control-Method"
  7. "Access-Control-RequestHeaders"
  8. "Access-Control-Request-Method"
  9. "Access-Control-Request-Methods"

It lets trakers (1) steal private data and (2) attack clients and servers. Cross-origin sharing (CORS) enables requests for (often hidden as dynamically-loaded and/or generated) 3rd-party contents like:

  • JS: players, captchas, charts, firebase, etc.
  • CSS: fonts, shapes, styles, pictures, icons
  • WebGL: textures, games, FX, tutorials, etc.
  • images, videos, sounds, audios, music, etc.

To be safe, DO NOT accept all requests from everyone, nor let serial law-offenders inject dynamically-loaded and/or generated active contents & authentication-bypass directives in your server replies!
(install the uMatrix Firefox extension to see how many third-parties are included in the Websites you think you browse "securely" ...and ask yourself why the MICROSOFT Edge and GOOGLE Chrome browsers prevent you from installing the open-source uMatrix extension)

HTTP/2-3's DoH TLS encryption facilitates theft by hiding who does what! You "delegate security" by paying untrustworthy 3rd-parties to certify that you are yourself... while this gold-standard of (sabotaged OS/libraries) security is completely bypassed by backdoored (patented!) randomness generators and hundreds of thousands of "root certificates" used by tens of thousands of government agencies and private companies – without oversight!

I STRONGLY ADVISE you to avoid using any security-bypass: it's DELEGATING THE SECURITY (of your sites and their visitors) to 3rd-parties that have been fined countless times by the US DoJ for having repeatedly violated the law (while stealing user data to sell them).

In fact these "standards" (and server/browser implementations) are so broken (and exploited by countless JS/CSS libraries, CDNs, fonts/pictures/videos repositories, etc.) that G-WAN servlets are the only place where access-control should take place: THEN YOU STAY IN CHARGE.

  • You don't want to send a file (or some data, or a whole website) to anyone NOT AUTHORIZED BY YOU?
  • Reply with a 403, 404, or 405 HTTP error!

G-WAN prevents dot-starting folder/file names from being queried by clients. Then, clients MUST query servlets like:
"/?app1&session=a182bcd6e4f5&user=f2b5de1745&file=9a78c54e9f" to fetch anything!

  • The above hexdecimal tokens are encrypted (with a secret by-session key) to prevent replay attacks (injected by authorized users).
  • G-WAN named-IP-whitelists protect this method further (preventing brute-force and cryptographic attacks)!
  • G-WAN servlets can serve any static file with 1 single line of code, it's easy!

To stop being trapped, hacked, ransomed, spied, sabotaged, and robbed – take back control on your security!

Anyway, the result is that G-WAN now parses over one hundred HTTP headers (both query and response headers) directly in a structure (the same method used since 2009), and has extra room for non-standard headers (your user-defined X-headers).

A structure gives direct access to all key/values, without CPU/RAM overheads. For Web applications, this is faster, more convenient and safer than hashmap lookups (where your application must specify the full header names to search any entry: with standard header names, there's no need to force users to repeatedly specify the full string names in their code).

G-WAN servlets: missing library header

δ

You need to install missing library headers. Here is an example for libc:

Linux Debian 64-bit running G-WAN 32-bit:

 sudo apt-get -y install libc6-dev-i386

Linux Debian 32-bit or 64-bit:

 sudo apt-get -y install libc6-dev

To find which package contains a given header file, install apt-file (available on Debian-based systems):

 sudo apt-get -y install apt-file             // install the apt-file tool
 apt-file update                              // load apt-file's definitions

Then use apt-file as follows:

 apt-file search sqlite3.h                    // search the missing header
 libsqlite3-dev: /usr/include/sqlite3.h       // here is where it can be found
 
 sudo apt-get install libsqlite3-dev          // install the missing package



G-WAN servlets: library undefined symbol

δ

If a library used by a C script with the #pragma link directive – or a system library – cannot be found by the linker, then.

Here is how to install the mysql client library:

 sudo apt-get install libmysqlclient

You will also need to install the library headers for development:

 sudo apt-get install libmysqlclient-dev

Sometimes, a library is not properly installed. For example, SQLite3 may be stored on disk as /usr/lib/libsqlite3.so.0.8.6 and /usr/lib/libsqlite3.so.0 but not as /usr/lib/libsqlite3.so which is the required form (usually a file system symbolic link or a hard link) to let applications find the library without knowing the library.so[.major.minor] version name. The solution is then to create the missing link:

 sudo ln /usr/lib/libsqlite3.so.0 /usr/lib/libsqlite3.so

This happens with pre-installed libraries on several Linux distributions. As a result, a G-WAN script using this library won't compile – causing the Web server to fail after it correctly started in daemon mode. The gwan/logs/gwan.log file will tell you what's wrong, and you can check if the problem is fixed by running G-WAN in the terminal (without the -d switch).



G-WAN servlets: using libraries

δ

On Linux, /usr/lib lists more than 1,000 pre-installed libraries. Millions of C libraries have been written in 40 years. G-WAN lets you use any of them by adding the #pragma link and #pragma include directives at the top of your C scripts:

#pragma link "sqlite3"                // link with the SQLite3 library
#pragma include "./libraries/sqlite3" // PATH to the SQLite3 headers (if not standard)

#include "sqlite3.h"                  // SQLite3 definitions
#include "gwan.h"                     // G-WAN definitions

int main(int argc, char *argv[]) 
{

If the library headers are properly installed in the system include PATH then you can use #include <sqlite3.h> instead of the #include "sqlite3.h" and #pragma include used above.

You must link 32-bit libraries to a 32-bit process and 64-bit libraries to a 64-bit process. To know how a given library was compiled, use the command below:

 file /usr/lib/libsqlite3.so.0.8.6
/usr/lib/libsqlite3.so.0.8.6: ELF 64-bit LSB shared object...

C++ libraries can be used from C programs by using an extern "C" {} wrapper around the functions that they export. This is neded because C++ is adding a non-standard (different for each C++ compiler) prefix before every function name to distinguish overloaded functions using the same name with different types or number of arguments (Google "C++ mangling" for more details).


G-WAN servlets: using libraries from gwan/libraries

δ

There are times when you want your scripts to call your own libraries (stored under the gwan/libraries directory instead of in the system-wide /usr/lib), to avoid duplicating routines in several scripts, and/or to avoid disclosing their source code.

This is precisely what the R&D team at stack GmbH needed to do, and they have sent us this short how-to to help other users (thanks for sharing).

Say you have lib2 relying on lib1, both of which stored in sub-directories under gwan/libraries:

  gwan/libraries/src              // lib2 source code
  gwan/libraries/dir1/libone.so   // lib1 location
  gwan/libraries/dir2/libtwo.so   // lib2 location

Here is the GCC command line to build lib2 to make it resolve lib1 when dynamically linked:

 gwan/libraries/src$ gcc -shared -o ../dir2/libtwo.so -Wl,-rpath=libraries/dir1 \
                               -L../dir1 -lone libtwo.c

Then the servlet will specify libtwo as usual:

#pragma link "./libraries/dir2/libtwo"
#include "libtwo.h"

Thanks to the -Wl,-rpath=libraries/dir1 linker switch used to build libtwo, libone (the dependency of libtwo), is resolved and dynamically linked at runtime.


G-WAN servlets: installing system-wide libraries

δ

If you have created a library called libmy.a (a static library) or libmy.so (a shared library), then you will use it from G-WAN in the same manner with a simple #pragma include, see the question above.

For static libraries (linked at compilation time with each of your scripts):

 sudo install -m 644 libmy.a /usr/lib 

For shared libraries (loaded once instead of being linked to each script):

 sudo cp libmy.so.1.2.3 /lib                                // files repository
 cd /usr/lib                                                // links repository
 sudo ln -sf ../../libmy.so.1.2.3 libmy.so                  // create a *.so link
 sudo ldconfig                                              // update the cache

Most of the time you will use shared libraries to save memory (saving memory helps a great deal for performance).

Static linking provides even better performance but may cause issues when mixed with shared libraries (ie: the LIBC runtime may not be the same, causing incompatibilities).

Further considerations:

As we have seen above, libraries may be installed under different directories, some under the system PATH like /usr/lib, /usr/local/lib, etc. (each Unix version and Linux distribution possibly using different conventions).

If you want to link against installed libraries in a given directory called MY_LIBDIR, then you must either use the libtool system command to specify the full pathname of the library, or use the -LMY_LIBDIR linker switch and do at least one of the following:

  • add MY_LIBDIR to the LD_LIBRARY_PATH environment variable at runtime
  • add MY_LIBDIR to the LD_RUN_PATH environment variable during linking
  • use the -Wl,-rpath -Wl,MY_LIBDIR linker switches
  • add MY_LIBDIR to /etc/ld.so.conf (or equivalent)

G-WAN handlers: how to trace crashes?

δ

The first thing to do is to add the following directive at the beginning of all your C/C++ scripts (handlers and servlets):

   #pragma debug

Then, the crash's backtrace will make sense as it will show the place where the fault took place (script file name, line number, and function name) instead of something like:

   #0  0x00007fa3169698ad in ?? ()
   #1  0x0000000000000000 in ?? ()


Durability: designed to support several OSes and CPUs

δ

In 2009 G-WAN was first written for MICROSOFT Windows, and a few months later ported to Linux (where it was faster – yet, this might no-longer be the case today, due to our rewrite of many system layers, but we will know only the day "Windows Defender" lets G-WAN be copied on a Windows hard-disk).

After 2015, G-WAN's portability has been extended because many system layers have been implemented in G-WAN to let it survive the recurring arbitrary system changes ("arbitrary" means gratuitous incompatibilities without any feature/performance benefit) that made G-WAN's code repeatedly crash (without stopping the server, yet with the effect of immensely slowing-down it).

G-WAN's Portability has reached a new level when G-WAN stopped using the GNU LibC (the Linux C runtime) on concerns of security (see the SLIMalloc report) and performance (see SLIMalloc's papers) because now G-WAN is now "statically-linked" (instead of relying on system shared libraries, it is mostly self-sufficient – a few OS-kernel syscalls are still needed).

Because G-WAN's code replaces many areas of the operating system's code, G-WAN can now run (with very little modifications) on Windows and Mac OSX, on AMD64 and ARM64 CPUs... and much, much faster than before (proof that the principal OSes have a large progress margin...).

G-WAN is written in ANSI C code, the most widely ported programming language in history. Sometimes people speculate that most of G-WAN is written in assembly language, and they (learnedly) conclude "hence its speed". But, in reality, very little is written in asm and usually this is for portability (on other OR or CPU platforms) rather than for raw speed gains.

We have received reverse-engineering attempt reports from people who (wrongly) concluded that, as their tools did not manage to reverse G-WAN's machine code into meaningful C code, or as they did not understand how this machine code can be generated from portable C code, G-WAN was necessarily using assembly language.

Many things in a server program can be done in portable yet efficient ways rather than in the usual academic (but sub-optimal) ways documented by universities in textbooks (the same texbooks used to build the C decompilers that fail to understand how portable yet efficient C code can be written).

Efficiency is not a gadget. Efficiency is mandatory for a server because servers process the requests of many, many clients in parallel (in contrast, clients only take care of one single task).

Since the early times of micro-computers programming, the costs of inefficiency have been raising exponentially because raising the operational costs is the only certain way for financed companies to capture 100% of the market. This is why G-WAN is so much faster than its competitors: as an entrepreneur that has never been financed since 1998, I have to care about my operating costs.


Recommended Operating Systems

δ

Debian remains a decent (relatively well documented) choice but there are smaller, more efficient distributions.

You must test an OS release before blindly assuming that 'newer' means 'better'. This is true for the Linux kernel and its distributions.

It's difficult to make definitive recommendations in a world where OSes change the way they work unpredictably (breaking backwards compatibility without notice) but common-sense should make one prefer server distributions that offer the smallest ISO images (having less code, they have less bugs, execute faster, and are also more stable).

Installing whatever is missing on a tiny core OS is much better than wasting days to figure how to identify and remove the mountains of things that you don't need at all and that should be uninstalled without breaking other things that have been arbitrarily made mandatory (removing these packages breaks the system).

If big players like RED HAT or ORACLE support their software applications only on their own Linux distribution, this is probably for a reason: predictability matters.


Hypervisors

δ

As G-WAN consumes 172 times less RAM than NGINX (on a 32-Core CPU) and delivers 3 orders of magnitude more RPS than NGINX, G-WAN is ideal for low-end and high-end machines, but also for virtualization layers (splitting a machine in several VMs, or aggregating many machines in 1 VM).

Yet, there's an issue with virtualization, an issue that is even more difficult to address than mere Linux distribution and/or version incompatibilities: hypervisors (Xen, VMWare, VirtualBox, etc.) alter the CPU instruction sets in violation of the specifications (like for the CPUID opcode) in addition to altering the OS behavior (most often in nonsensical ways: "free RAM > total RAM", "0 CPU", "0 Core", broken kernel structures, etc.).

Worse, these VMs can be "tuned" by the people configuring them, in ways that break even more things. That's why "bare-metal machines are so much more reliable than VMs (that add their own vulnerabilities to the HW and SW stacks!).

It can be frustrating to see other Web servers run fine on hypervisors while G-WAN may have problems. This comes from the fact that legacy Web servers are not designed to (decently) support multicore: users are supposed to run several instances of each single-threaded server:

    PID  THRDS  %CPU     VIRT    RSS      SHRD  EXE
   2575      1   0.0  20.9 MB  1.8 MB    1.0 MB  nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
   2576      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2577      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2578      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   2579      1   0.0  22.9 MB  4.0 MB    2.7 MB  nginx: worker process
   ...

...and to manually tie them on different CPU cores, with the inefficiencies (like shared memory) and redundancies (duplicate code and data structures) that G-WAN was designed to address... that is, on deterministic machines (rather than yoyo unreliable VMs):

 > ./gwan -p
- running gwan process(es):

    PID  THRDS  %CPU    VIRT      RSS   SHRD  EXE
 537230     17   0.0  6.9 MB  768.0 KB   0.0 KB  /opt/gwan/gwan :8080

To find and resolve these hypervisor issues, constant compatibility checks should take place, but this is well beyond our needs (remember that G-WAN was developed to fill a gap in our infrastructure) and, unless a client pays for this extra work, we can't justify the effort from a financial point of view, as hypervisor vendors do not document their (ever changing) erratic behaviors.

Again, if vendors like ORACLE or Red Hat only support their own "certified" (translate "stable" or "well-known") version of Linux, that may be for a reason.


Open-Source (License)

δ

G-WAN is a freeware. It means that it is free for all (commercial users included). Yet, we can often read the fallacy that "a product without its source code cannot be used because it cannot be trusted".

Ahem... surely they don't use a car, a TV, a cellular phone, a voice answering-machine, a fax, or even a washing-machine, right? These devices are not open-source, nor their online updates and add-ons tunnelled by IoT service providers.

How can they use a computer? Even Linux relies on closed-source software: proprietary drivers, codecs and firmware (keyboards, BIOS, hard-disks, disk controllers, video boards, network cards, printers, Wifi stations, etc. some of which are notoriously used to hack remote computers).

But this 22-year-old X Window critical security hole will surely convince the most reluctant "security experts" about how seriously scrutinized the most widely used open-source software (in this case, all Unix flavors) is – and how competent the security auditors are about providing a valuable service... in reality (that is, beyond the claims and the empty promises).

Like their closed-source peers, open-source "trusted security" champions, such as the OpenSSL Foundation (among many others), are officially paid by governments to backdoor the whole ecosystem (Windows, Mac OS X, Linux, Solaris, BSD, OpenVMS, IBM OS/400, hypervisors, security appliances, smartcards, firewalls, VPNs, etc.).

So, claiming that the so-called "many-eyes" open-source policy is a guaranty of security is mere propaganda: your secret keys (SSL certificates, SSH connections, OS updates, etc.) are happily processed by NSA-backdoored Operating Systems and libraries (and bypassed by hundreds of thousands of "root certificates" nullifying the security promise)... a fact that no open-source blogger or open-source company feels the urge to denounce – and even less criticize... despite plenty of corporate and academic evidence:

"The 'many eyes' of open source are blind, uninterested, or selling to governments for profit."
– Brad Spengler, Open Source Security, Inc. (2012)

"No amount of source-level verification will protect you from using untrusted code."
– Ken Thompson, "Reflections on Trusting Trust", Communications of the ACM, volume 27, number 8, pages 761-763

The "trusted" operating systems run on unsafe-by-design "shared libraries" to enforce this vulnerability (your applications run unsafe code provided by the ones eager to use their backdoors against you). Read my second SLIMalloc paper if you are still in doubt – or need to discover the sad truth in more graphic details.

Another fallacious argument is that "having the source code lets the community find hidden vulnerabilities".

  1. Most security-holes are found by running binaries: executables are the end-result (due to compilers and shared libraries);
  2. Despite MICROSOFT products being closed-source, new security holes are inserted and found constantly;
  3. Despite being open-source, Linux, Apache or NGINX expose endusers to new critical vulnerabilities – every single year.

G-WAN makes more efforts than others to be trustworthy: no vulnerability was found since its first release in 2009. This was so unacceptable for our "trusted" competitors that in 2011 they have felt the need to forge a fake advisory.

That's the same benevolent (and security-concerned) people (working for Defense contractors, the GAFAM, and the US DARPA or DoD) that have mercilessly censored SLIMalloc – an historic computer-science advance resolving "memory-safety", a major cyber-security issue for which the White House requested a solution "to protect the U.S. economy".

Another fallacious argument is that G-WAN would no longer be supported if its author disappeared.

Given G-WAN's performance after 17 years of existence, I would rather worry for all the other (immensely inferior) HTTP servers, because there is absolutely no way (other than robbery or buying a G-WAN source code license) to upgrade them to G-WAN's level.

Further:

  1. Big companies die (Compaq, DEC, SUN...) or discontinue product lines (MICROSOFT PDS-Basic, Visual Basic, etc.);
  2. To this effect, G-WAN provides a source code insurance to secure people's investment in case of support interruption;
  3. If NGINX modules are such a pain to create and use, fixing its uncommented and bulky source code is even harder:
serverbirthfilesindentationblank linescomment linessource code linestotal lines
Apache1995368K&R variant29,44048,55877,951155,949
G-WAN2009171Allman11,19842,70656,766110,670
NGINX2002256K&R variant35,1314,30894,369133,808

G-WAN, while using a more readable indentation and more comments, needs less source code lines to offer more features.

The open-source argument is clearly mis-used by some vested bloggers to spread F.U.D.:

  • G-WAN is free for all – and users can subscribe to support plansjust like for the less capable open-source servers;
  • G-WAN offers licensing options to those software vendors who want to benefit from G-WAN's so fruitful years of R&D.
  • G-WAN was written because other Web application servers are a pain. At TWD Industries AG we needed a better tool.

And, instead of keeping G-WAN for the company he founded in 1998 Pierre released it as a freeware for all to benefit from it.

  • End-users: just need to have the job done – at the best cost (cost-reduction is what makes a faster server appealing in the first place). And since G-WAN can be used gratis, there is no way to reduce costs any further;
  • Software vendors: using others' many years of R&D for free is appealing: they can 'fork' the code, put their name on it, and sell licenses (or Cloud subscriptions) without ever contributing to the project that fuels their business. Since the U.S. Dept. of Justice fails to punish the big companies that violate US and international laws, startups and smaller firms don't have a chance.

Next time someone feels the need to publicly call G-WAN's (1-page) license "weird" or "insane", look at what they sell and who they get their revenues from. And, guess what, on the top of forcing you to burn cash at wasted hardware resources or to expose your network infrastructure and your data to spies and crooks, unlike G-WAN, what they offer is not free at all.


Human-readable Crash Reports and Automated Disaster-Recovery

δ

If a G-WAN script crashes, then the server continues unharmed, issuing a detailled (SLIMalloc) crash report, either interactively (in the terminal) or in the gwan/trace log file:

  Error[SIGSEGV SEGV_ACCERR] @ mem:0x4ad65b in 'text'
   VMA beg: 0x4a6000 size:112.0 KB perm:r--p dev:103:0 inode:5 name:60162055
   VMA ptr: 0x4ad65b (30299 from beg, 84389 from end)
   VMA end: 0x4c2000
   | 74 6f 74 6f 00 67 69 66  00 20 55 54 43 00 32  |toto.gif. UTC.2|

  date: 2025.04.02 09:08:23 (UTC)
  in  : gwan pid:18080 tid:18085 @ pc:0x42fbf6

  dist: Ubuntu 24.04 LTS
  host: IBM-14
  gwan: v17.04.02 (2025)

  stack-frame   code-addr        function                      file :   line
  --------------------------------------------------------------------------
  7fc6818b8040  42fbf6    servlet_crash()   gwan_servlets_examples.h:    577
  7fc6818b9230  43b6e1        th_worker()                     gwan.c:   7208

Presented for humans (unlike the OS "core dumps"), you have all the information required to find exactly what went wrong and where (no more vodoo mysteries happening in production when nobody is watching).

If the G-WAN process crashes/freezes itself (since 2009 we haven't seen this happening consecutively to receiving client data), then the parent process (kills a frozen child if any and then) restarts a new clean child process.

In any case, a G-WAN server crash and restart is stamped and logged in the gwan/trace log file, and a crash report is also issued here, with a backtrace when available (ie: when the thread stack was not corrupted).

The break-down of threads in a child G-WAN process is explained here. In the past, G-WAN started as many worker threads as your server had physical CPU Cores. Now, G-WAN starts small and grows (and shrinks worker threads) on-demand – to spare CPU/RAM resources and achieve better performance.


Caching

δ

Despite its small footprint, G-WAN is an all-in-one solution because communicating with other servers (FastCGI, SCGI, etc.) takes time (enlarging latency), and wastes CPU and RAM resources when the network can be avoided. Also, supporting many programming languages lets G-WAN serve most needs instead of having to use slower backend servers and fontend caches. Remember that our goal here is to use the ultimate low-latency and resource-saving solution. This is why G-WAN is a:

  1. Web server
  2. App. server
  3. Cache server
  4. Key-Value store server
  5. Reverse-proxy and elastic load-balancer server

To cache a file or a page generated dynamically, you can use the G-WAN Caching API with cacheadd(), cachedel() and cacheget() implemented via the G-WAN 'wait-free' KV store.

But this feature does not replace dedicated cache servers (also called "Web accelaration servers") like NGINX (which has a cache activated by default, see its --without-http-cache compilation option used by proxy_cache and fastcgi_cache) Varnish or Apache Traffic server (ATS) which are used to transparently cache the data served by backend servers.

To reduce the need for a frontend cache server (and to let G-WAN be used as a caching reverse-proxy) You can enable G-WAN micro-caching, a RESTful feature disabled by default (see the gwan/init.c file).

When a given URI is invoked at high concurrencies and when generating the payload take a lot of time, then G-WAN will automatically cache a page for 200 milliseconds (the average latency on the Internet) to make sure that the cache is up-to-date: within 200 ms, consecutive requests provide the expected result.

Requests using cookies are not cached as they are intended to be unique for each user. To use caching on a per-request basis, enable the caching feature and disable caching by using a changing query parameter (per user session id, random, counter, etc.) or use the RC_NOCACHE return value for servlets. Obviously, the cache is also disabled if a servlet returns RC_STREAMING.

But G-WAN is very fast even without micro-caching because:

  • G-WAN allows dynamic contents to be generated faster than the same LIBC-based program (either stand-alone or Apache/NGINX pre-compiled modules).
  • G-WAN is a faster server even when micro-caching not triggered: caching hello world would actually slow-down things by involving a cache lookup where a simple static string copy is faster. Because G-WAN App. server is a faster server it serves small payloads much faster than the fastest Web servers.

When a G-WAN script has to make slow calculations (loan) or to fetch a value from a (database) backend server, the network is slow and a database is even slower so they will both produce high latencies. In this case, caching is the only way to serve hundreds of thousands of concurrent requests with a single server.

At the ORACLE Open World, G-WAN has accelerated ORACLE noSQL to reach 1.2 billion TPS on a 6-Core machine. That was done by working as a cache between the 45,000 live users (and 100 millions of bots) stored by ORACLE noSQL.

For more common applications, the point of micro-caching is to avoid the need for yet another server process burning cash on another dedicated machine because G-WAN works fine as a cache (see Varnish compared to G-WAN).

Caching is so important that the Internet is heavily relying on distributed proxy servers (CDNs or gateways at ISPs and enterprises) and local caches (in Internet browsers like Firefox, Chrome, Opera or IE) to speedup requests and spare resources (it is pointless to fetch a valid answer already made available in the past).

Caching is also used in CPUs (that's one of the rare ways that make it possible to run non-parallelized code faster on multicore), disk controllers as well as file systems for the very same reason: saving time and resources that can be better allocated elsewhere. We as human beings call it "short-term memory" and we could hardly work without it.


Changing the PATH environment variable

δ

You have to change the PATH variable if you want to call programs without specifying their location.

The PATH is defined in the file /etc/profile. It applies to all users. This is a colon-separated list of directories that you can list as follows:

 $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Edit the PATH as follows:

 sudo gedit /etc/profile

After modification, reload the PATH:

 . /etc/profile
or
source /etc/profile

You can find the PATH of a program by typing:

 type apache2
apache2 is /usr/sbin/apache2

or

 which apache2
 /usr/sbin/apache2



Setting ENVIRONMENT variables

δ

Many examples here explain how to use the export command to change session-wide environment variables for one user. But if you want those changes to be permanent and system-wide then do that:

 sudo gedit /etc/environment                        // add environment variables
source /etc/environment                            // reload environment

Here you would have to add variable definitions like:

JAVA_HOME="/usr/lib/jvm/java-6-sun"

If you decide instead to use the ("less recommended") /etc/profile configuration file then do this:

 sudo gedit /etc/profile                            // add BASH commands
 source /etc/profile                                // reload profile

Here you would have to add BASH commands like:

 export JAVA_HOME="/usr/lib/jvm/java-6-sun"

We publish this information because we belive that it may be useful to those who do not know (yet) how to proceed. Reading the dedicated Ubuntu help page makes it clear that, oddly, this is not a trivial issue.


Why are ENVIRONMENT variables ignored?

δ

You have defined environment variable like above and they have no effect. Chances are that you are using sudo which does not load the system wide variables... unless this is explicitely requested:

 sudo -i                               // load environment variables
 cd /opt/gwan                          // go to the G-WAN directory
 ./gwan                                // start G-WAN with environment variables

This sudo problem does not exist with the regular root account most likely used on a production server.


Service Mode

δ

To start G-WAN as a service (make it start automatically at boot time) use the script below:

#!/bin/sh
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/usr/local/bin/node" 
SUPATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/usr/local/bin/node" 
CLASSPATH=$CLASSPATH":/usr/share/java/scala-library.jar" 
export PATH CLASSPATH ENV_SUPATH

### BEGIN INIT INFO
# Provides:          G-WAN
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: G-WAN initscript
# Description:       This initscript starts and stops G-WAN
### END INIT INFO

# Author: Thomas Meitz, gwan at jproxx dot com
# Modified by: Fnux, fnux.fl at gmail dot com (environment variables)
# Version: 1.3 as of 10.27.2013
# Note: (edit the GWAN_PATH variable if G-WAN isn't installed in /opt/gwan_linux64-bit)
# 1. copy under /etc/init.d 
# 2. chmod 775x /etc/init.d/gwan
# 3. update-rc.d gwan defaults 95 5

NAME=gwan
GWAN_PATH=/opt/gwan_linux64-bit
TEST=""
START="-d"
STOP="-k"
VERSION="-v"
SCRIPTNAME=/etc/init.d/$NAME
STARTMESG="\nStarting TrustLeap G-WAN Web Application Server in deamon mode."
UPMESG="\n$NAME is running."
DOWNMESG="\n$NAME is not running."
TESTMESG="\nStarting Trustleap G-WAN Web Application Server in client mode.\nHit Ctrl+C (or close the terminal) to stop G-WAN."
STATUS=`pidof $NAME`

# Exit if G-WAN is not installed
[ -x "$GWAN_PATH/$NAME" ] || exit 0

case "$1" in
  start)
        echo $STARTMESG
        cd $GWAN_PATH
        ./$NAME $START
        ;;
  stop)
    cd $GWAN_PATH
        ./$NAME $STOP
        ;;
  status)
    if [ "$STATUS" > 0 ] ; then
        echo $UPMESG
    else
        echo $DOWNMESG
    fi
    ;;
  restart)
    cd $GWAN_PATH
    ./$NAME $STOP
        echo $STARTMESG
    ./$NAME $START
    ;;
  version)
    cd $GWAN_PATH
        ./$NAME $VERSION
        ;;
  test)
    cd $GWAN_PATH
    echo $TESTMESG
    ./$NAME
    ;;
  *)
        echo "Usage: $SCRIPTNAME {start|status|restart|stop|version|test}" >&2
        exit 3
        ;;
esac
:

To install the script above under /etc/init.d/gwan and run it (under Debian):

 gksudo gedit /etc/init.d/gwan        (paste the script above and save the file)
 sudo chmod 755 /etc/init.d/gwan      (change the file access rights) 
 sudo update-rc.d gwan defaults 95 5  (after this, reboot)
 sudo service gwan start              (start the gwan service)


Cron Jobs (maintenance)

δ

cron is a system tol used to start periodic tasks at a given time (see man cron and man crontab for more details). It can be used to stop and restart G-WAN, run system integrity checks, make backups, transfer log files, etc. Here is an example for Ubuntu:

# this system configuration file is stored as /etc/cron.d/gwan

# modify as needed
#PATH=/usr/sbin:/usr/sbin:/usr/bin:/sbin:/bin

# restart /opt/gwan/gwan daily (UTC time) every day
# Syntax: MIN(0-59) HOUR(0-23) DAY(1-31) MONTH(1-12) WEEKDAY(0-6) ACCOUNT COMMAND(S)
# (unlike '&&' which stops at the first error, the ';' command separator ignores errors)
00 16 * * * root /opt/gwan/gwan -k;/opt/gwan/gwan -d:www-data

Other Linux distributions may use another system PATH to store cron jobs (check your system's man pages).


Support of Programming Languages

δ

As G-WAN supports scripts in many languages (C/C++, C#, PHP, Java, Javascript, Lua, Go, Perl, Python, Ruby, etc.), people invariably ask how their (currently unsupported) favorite language can be made working with G-WAN.

This is not always easy because of many factors, among which the most common problem is the lack of (correct and/or up-to-date) documentation from the language vendor.

If you want to use a new language with G-WAN then contact us. Having built more than a dozen of interfaces so far, there's chances that one more can be added if people provide the relevant information.


Setup of Programming Languages

δ

G-WAN progressively added programming languages for servlets (but G-WAN handlers can bypass servlets and support any other programming language):

  • asm ............... v1+
  • C ................. v1+
  • C++ ............... v3.1+
  • C# ................ v3.8+
  • D ................. v3.1+
  • Go ................ v3.10+
  • Java .............. v3.2+
  • Javascript ........ v3.10+
  • Lua ............... v3.10+
  • Objective-C ....... v3.1+
  • Objective-C++ ..... v3.1+
  • Perl .............. v3.10+
  • PHP ............... v3.10+
  • PH7 ............... v4.11+
  • Python ............ v3.10+
  • Ruby .............. v3.10+
  • Scala ............. v3.9+

As you can see, G-WAN v3 has worked hard to offer many more programming languages to let almost all developers benefit from multicore CPUs.

A G-WAN user has generously donated a bash script to install these 15 languages (and the ab.c/weighttp benchmark tool) on many Linux distributions (Debian, LinuxMint, CentOS, Fedora, RedHat, Manjaro, Arch Linux and Bridge). The installation menu is available in English, German, French and Spanish!

Version numbers are formatted as [Year.Month.Day]. Some of the version numbers listed above were non-published beta releases available for registered users (at the 'Enterprise' level or greater) or for partners who have helped with those technologies. The '+' following a version number means that any more recent version supports the specified language.

To develop in C you have to install GCC, the C compiler:

 sudo apt-get install gcc build-essential

To develop .NET C# applications you HAVE to download the source code and build the C# runtime:

 wget http://origin-download.mono-project.com/sources/mono/mono-3.0.2.tar.bz2
 tar -xjf mono-3.0.2.tar.bz2; cd mono-3.0.2
 sudo ./configure --prefix=/usr; make; make install

On Ubuntu 10.x the Mono packages contained the necessary files but this is no longer the case.


GAC libraries can be linked to your G-WAN scripts by using the following comment at the top of your script:

 // pragma link mylib

Other C# libraries can be forced to be linked with all your G-WAN scripts by copying the *.dll files in the /.../gwan/libraries/cs/dll folder.

The D programming language requires you to write "extern (C)" before all (translated in D) gwan.h prototypes (see the hello.d example). The D import replacement for the C include directive could probably be used – if only its file-system mapping was documented). Any help in this matter is appreciated.

For Java, use the OpenJDK or the SUN/Oracle JVM. G-WAN + OpenJDK has a 20 MB footprint on Linux Debian 6 64-bit (the JVM is loaded only if a /csp folder contains *.java scripts).

 sudo apt-get install openjdk-7-jre
  • To specify which Java VM you want to use, define the $JAVA_HOME environment variable:
     export JAVA_HOME=/usr/lib/jvm/java-6-sun
     export PATH=$PATH:$JAVA_HOME/bin

    You can clear an environment variable with the command: unset JAVA_HOME

  • To load external classes with import, add their path to the $CLASSPATH environment variable:
     CLASSPATH=$CLASSPATH:/.../myclasses
     export CLASSPATH

  • To load JAR archives with import, add them to the $CLASSPATH environment variable:
     CLASSPATH=$CLASSPATH:/.../myclasses.jar
     export CLASSPATH

NOTE

In the past, G-WAN was using the javac compiler of its corresponding JVM, and both were loaded from the same jdk/bin directory branch. As recent versions of Linux have removed the javac compiler from its corresponding jdk/bin directory, G-WAN is using the JVM compiler found in the PATH when this is hapening. If you don't want that to happen then create a jdk/bin/javac link pointing to the right javac compiler (the one really matching the JVM that you have specified).

If Java Scripts Do Not Work

 1. delete all openjdk pakets
    a. sudo apt-get purge openjdk-\* icedtea-\* icedtea6-\*

 2. Download Java 7 from Oracle and uncompress into /opt directory
    a. http://www.oracle.com/.../downloads/jdk7
    b. move the download to /opt
    c. cd /opt
    d. gunzip jdk-7u10-linux-x64.tar.gz
    e. tar xvf jdk-7u10-linux-x64.tar

 3. edit /etc/profile (put these line to the end of the file)
    a. export JAVA_HOME="/opt/jdk1.7.0_10"
    b. export PATH=$PATH:$JAVA_HOME/bin

 4. relog

This Java troubleshooting procedure has been provided by Thomas Meitz, gwan at jproxx dot com

Scala relying on the JVM, it requires the same dependencies needed by Java, check the tips above to make sure that a JVM can be used for G-WAN scripts. When this is the case, you can install and configure the Scala runtime:

 sudo apt-get install scala

If scalac cannot be invoked from a prompt then create $SCALA_HOME and add it to the PATH:

 export SCALA_HOME=/usr/share/java
 export PATH=$PATH:$SCALA_HOME/bin

Then you MUST include the Scala runtime and libraries in the Java $CLASSPATH:

 CLASSPATH=$CLASSPATH:/usr/share/java/scala-library.jar
 export CLASSPATH

Oddly, this last step in not done by the Scala installation (which has added the SCALA_HOME to the PATH for me). When it is missing (like that was the case for me) then the first time you will run a scala servlet you will get the following error:

 Exception in thread "..." java.lang.NoClassDefFoundError: scala/ScalaObject

This error means that the Scala runtime was not found by the JVM.

To install the Javascript runtime on Debian, run the following command:

 sudo apt-get install nodejs

Your're done... that is, if you have the latest Debian/Ubuntu release. Else, many things are broken so you should rather install manually (install the latest source code archive by replacing the version number below):

 wget http://nodejs.org/dist/node-v0.6.12.tar.gz
 gunzip node-v0.6.12.tar.gz
 tar -xf node-v0.6.12.tar
 cd node
 ./configure
 make
 sudo make install  

To install the Google Go runtime, download the latest Go binary package or source code.

To install the binary package do this (replace the version number by yours):

 sudo tar -C /usr/local -xzf go1.0.3.linux-amd64.tar.gz

Then, add Go to your PATH (you can do it permanently in the /etc/environment file):

 PATH=$PATH:/usr/local/go/bin

Note that sudo ignores the /etc/environment file unless you run "sudo -i" to force sudo to load the /etc/environment file. Then, you will have to cd to the G-WAN directory and run the ./gwan program.


We initially made Go benchmarks by using the Ubuntu 10.10 package below but users reported that this is no longer working:

 sudo add-apt-repository ppa:gophers/go
 sudo apt-get update
 sudo apt-get install golang

If you have installed the golang package in the past then you will have to remove it before installing the latest version:

 sudo apt-get remove golang

To install the Lua runtime, run the following command:

 sudo apt-get install lua

Objective-C requires the following dependencies:

 sudo apt-get install gobjc gnustep gnustep-devel build-essential

If, when compiling, you get the kind of errors below:

 Foundation/NSObject.h: No such file or directory

Then, create the links below:

 sudo ln -s /usr/include/GNUstep/Foundation /usr/include/Foundation
 sudo ln -s /usr/include/GNUstep/GNUstepBase /usr/include/GNUstepBase
 sudo ln -s /usr/include/GNUstep/ObjectiveC2 /usr/include/ObjectiveC2

Run the following command to install the Perl runtime:

 sudo apt-get install perl

Run the following command to install the Python runtime:

 sudo apt-get install python

Run the following command to install the Ruby runtime:

 sudo apt-get install ruby

On Debian, run this command to install the PHP runtime:

 sudo apt-get install php5-cli

G-WAN supports many PHP-specific environment variables, including $_GET and $_POST, see the hello.php example.


G-WAN supports another PHP runtime called PH7 (from Symisc Systems SUARL) that you can install by doing this:

 1. download the PH7 'amalgamation' source code

 2. compile PH7 (-m32 is for 32-bit, -m64 for 64-bit):
     gcc -m32 -Os -o libph7-32.so ph7.c -fPIC -shared -fstack-protector-all -D PH7_ENABLE_THREADS
     gcc -m64 -Os -o libph7-64.so ph7.c -fPIC -shared -fstack-protector-all -D PH7_ENABLE_THREADS

 3. copy the shared library (libph7-xx.so) in the gwan/libraries/ph7 directory

Then, G-WAN will be able to run *.ph7 scripts (so you can run both *.php and *.ph7 scripts at the same time from G-WAN). Of course, you can define either PHP or PH7 as G-WAN's default language and omit the extension when invoking scripts.

What's the point? PH7 can be made thread-safe. Therefore, it can run directly from a multi-threaded process like G-WAN. This allows PH7 to be much faster and scalable than PHP (which crashes if more than one worker thread is running the Zend VM). This is why PHP has to be used as a (slower) CGI/SCGI/FastCGI process by G-WAN.

PH7 currently supports quite a large subset of PHP, but the PH7 authors said that they will add missing (core and library) calls if they are sponsored. At 500,000 requests/second on a 6-Core without caching(!), this is certainty an option worth exploring.

A suggestion to enhance these FAQs? Let us know.

Questions Not Answered Here

δ

The first 2010 G-WAN Forum has been put offline (by their maintainers) in September 2012. It has been revived 3 times (by G-WAN users) and taken-down every time it reached 5k users (a hint that the same people were at the switch). This Forum was aimed at G-WAN users and programmers search for replies to common (and less common) questions, but I have also answered many general-programming questions (like on Stackoverflow), probably leadnig to too much unwanted disclosure: (the technical level was well beyond what can be found in university courses), hence the censorship.

G-WAN (like SLIMalloc!) was also censored from Wikipedia (where both are absent, like RA, TWD's first product shipped in 1998), and WikiVS (now the whole site is offline, and G-WAN's page is archived here) by... the CEO of Varnish: I took him red-handed deleting the G-WAN page more than 50 times in a row, while using an IP anonymizer to hide his corporate IP address (at the time, he asked me by email not to destroy his life, as he would "lose his job and break his family" – yet he never stopped "slandering G-WAN" with his friends, hence this late disclosure).

Stackoverflow proved to be an unsafe place to ask and get technical tips (using the [g-wan] tag). Between 2009 and 2013, our accounts have been deleted 3 times – with all the related Q&As. Later, our account survived only to see periodic purges of our most voted replies about [g-wan] and [c]. I am not aware of any other Web server having received such a treatment (maybe because they are are slower than the official ever-funded champions... which are hundreds of times slower than G-WAN).

Since 2009, MICROSOFT Windows "Defender" and the MICROSOFT VIA (Virus Information Alliance) keep erasing G-WAN, even before the executable can be copied on disk, or executed. MICROSOFT also owns LinkedIn, which has "suspended" my account (I can't login, and my profile but also all the articles and comments I have published are invisible on the site).

The problem is that too much money is given to the wrong people to do the wrong things in total impunity, while too little Computer Science is allowed to take place. A very toxic mix.

So, to get a reply, it's much safer to just contact us.