Basically, nginx defines the notion of module to be a group of handlers (remember my previous post) that it will trigger at different points in its life-cycle (basically starting the master process, starting the children/worker processes and death of those). That's it... Now, the smart thing (but also the confusing one) is that a given module can refine what a module is. And that's exactly what you get with HTTP modules: they are specialized modules. There is one "core" module called "http" (
http/ngx_http.c) and this module basically defines what "http" modules are and how they are managed. Other types of modules include "core" modules, "event" modules (that's how nginx copes with various event-based interfaces like epoll, kqueue, select, etc.), "http" modules (the most common ones) and "mail" modules. But you could have your own type of modules. This is a good design and I take for a proof of this that Igor was able to build both a mail and an http server from this.
Now, after saying something nice about this design, there is something in the code that does not make sense to me: the implementation of versions of the module architecture. It's everywhere in the code with reference to the macros
NGX_MODULE_V1/NGX_MODULE_V1_PADDING. There does not seem to be any example of modules with anything but version 1. I understand the need to have a version (NGX_MODULE_V1): it gives you a criterion to figure out what is the right version of the struct that is used and allows you to cast safely. But the padding is just killing me: the structure already has spare "slots" and the existing mechanism with module types gives already plenty of room for changing what a module is. And if the structure (without padding) would prove to be not enough, you could always extend it with a "larger" structure and cast it. I guess that's another question I will have to ask the development mailing list. At least, it will get discussions going there.