Embedded Web Server

From Armagetron
Revision as of 11:08, 23 August 2021 by Cadillac (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The embedded web server is intended to provide a default installation of the dedicated server that is capable of serving its own resources to clients, providing a statistics page for players, and providing a remote administration function for administrators. It's not intended to replace in-game admin, of course, but to supplement it. As additional stuff gets added, it should be possible to add things to the web interface like managing tournaments and other things I'm not thinking of right now.


The web server uses a neat little program called shttpd. It's a program written with the intent of being an embeddable webserver and is used on some routers. It has a very liberal license that is compatible with the GPL, allowing us to include it in the game. It's a C API that supports callbacks, CGI, and some other things.

Serving Resources

This is only partially implemented. I added to the web server the ability to put multiple mount points under the web root so that we can put the resource directory under the web root. There's a couple of things here left to implement. Mainly the game server needs to be able to tell clients a proper URL for resources that uses this web server. Then there needs to be some config items for administrators to use to configure the web server's resource service.

It is this need that primarily introduces the requirement that the webserver be available in the regular client distribution. When a player wants to host a game from his machine using his game client, he should have this web server available to serve his resources.

How the embedded server will interact with the resource server


Player Web Pages

This is only half-baked right now. We have several options.

  • CGI

The CGI doesn't currently work in our embedded setup. This needs some troubleshooting. We should support it since it's there and server admins will probably want to be able to use it, even if we don't. In any case, we can provide an interface for players by writing simple CGI scripts, or even writing some C++ programs to do it if we don't want to introduce a scripting dependency for this.

  • Callbacks

This is the most likely way we'll go in the foreseeable future. Using the callback interface of the webserver, we can provide pages generated by C++ code in the armagetronad-dedicated process.

  • Python

After we have embedded Python, this is the most logical way to go, in which case we will likely still have the scripts executed inside the armagetronad-dedicated process, they'll just be Python scripts instead of C++ code.

Administrator Web Pages

So I created a callback for the /admin url. Smile So after you have it running you can visit http://YOURSERVERWITHPORT/admin?cmd=SOMECOMMAND&value=VALUE

And that command will be executed. Smile I'm going to look next hopefully into putting some protection on that url so a user and pass will be required, hopefully configurable somewhere. Smile But I figured that would be a good start to see if I could do it, anyway.

Configuring the Web Server


Old Stuff (left here for reference)

Remainder taken from the forums

In any case, the web interface now uses its config file. It's still a little messy in one spot, but I'll clean it up. I logged in to the dedicated server with a game client and then hit the web server and noticed no problems with the polling or anything. Since I set the web server to compile in multi-threaded mode, it should start a new thread for every page request, so they shouldn't be served from within the game loop, although the polling for new connections is done in the game loop. (This is what has so far saved me from having to make the uWebInterface class start its own thread)

For the repository thing, there's a reason I don't want to make a configuration option for the embedded web server as a repository. It should happen automatically. I.e. you set MAP_FILE and if you set no repository, the embedded web server should serve it automatically, and it should already know where the file is located and the client shoudl request it properly. But you want to support the resource repository, where if the client doesn't have the map, it knows about the resource repository. So, to support both scenarios, a simple flag should tell the server to tell the client to look at the resource repository instead.

This isn't mutually exclusive with the RESOURCE_REPOSITORY item you've mentioned, because a third and perfectly valid scenario is for the server to direct the client to a different resource repository that's not the central repository you're building.

Let's see. Sets the webroot to the repository directory. I have a small problem here. I'd like to make it work with cgi scripts and let server admins stick their own scripts on there if they have a cli php or python. If I set the webroot to the repository directory, then server admins have to put web interface files in it. We have to also, for images and stuff. If I set the webroot to something else, I need the resource repository under it. A copy isn't quite right, and there isn't (yet) any way to specify a callback for a specific directory, only for a specific url. I looked at modifying the web server for that and didn't find the solution, but of course I've only just started looking at the web server code.

So I created a callback for the /admin url. Smile So after you have it running you can visit http://YOURSERVERWITHPORT/admin?cmd=SOMECOMMAND&value=VALUE

And that command will be executed. Smile I'm going to look next hopefully into putting some protection on that url so a user and pass will be required, hopefully configurable somewhere. Smile But I figured that would be a good start to see if I could do it, anyway.

I think we can have the master tell the server what it's external IP address is, and then it could assemble a URI from that. For the sake of having it Right, I'd be happy to have that, but it still has to work even if there's no master server to give up this information. Wink (Especially considering it needs to work in a default installation, and a default installation has talk_to_master 0 set)

Ok, I'm done for the night. Here's what else I added:

www-root directory for web interface files. Probably I'll be adding an admin directory to it which will provide the admin functions I've been working towards, but it's not there yet.

Stuff to tDirectories that's probably wrong. Sad I admit I was quite confused reading that file. I want a call to tDirectories to a method just like GetDirPath() for resources, but I want it to return the path for www-root.

I also ran into a minor problem. Smile I'd like the build system to somehow copy the files under www-root to the build directory, wherever it's at. I'm at something of a loss for that, probably because I need to go to bed.

Still need to add the config option that tells the client to get resources from the embedded webserver and then the code to the client that actually does it. Anything else in this area is dressing. But as it stands right now, the URI should be http://SERVER:PORT/resource/PATH/TO/RESOURCE as Luke-Jr requested. So the client needs to know what the PORT is as well. To add that the way I was wanting I need to transfer the webserver config items to nSettingItems as appropriate, others to other types of course, and then add a series of calls in uWebInterface::Initialize() to initialize the webserver with them, and remove the webserver's call to open its own config file, adding that instead to the dedicated server itself. Most of the options should just stay the same as in the webserver, but some need to be changed (PORT being one of them, it's taken, and too ambiguous anyway).

Other than that, I'm not too far off from having a basic web-based admin GUI for the server and also having it serve up its own resources. Technically it can already do that if you put the right MAP_URI in your config file for it. This is no longer true. MAP_URI has been removed, as it is possible to write the MAP_FILE as "directory/file (http://some.server.com/another_directory/file; http://alternative.server.com/alternative_dir/file)". Also, I think there are 2 resource repository configuration items, one for the client, one for the server. IIRC, the server could point to its onw web server this way.

ANd, in the process there's no telling what I broke. Hopefully not much, because tDirectories is the only file I've touched outside of uWebInterface and the shttpd files.