This week a lot of hours has been spent working with the http refactoring, finishing location plugin chains and implementing some general improvements. A large emphasis has been put on making the http implementation support both current and new plugins. But while the new plugin api is protocol agnostic, the current plugins can not work with SPDY or HTTP/2.0.
# HTTP refactoring The result of the http work is a separation of the code into three parts, one part generic, one part to support the old plugin system and another to integrate with the new plugin api. Due to how current plugins work, they are not completely isolated as stages need to be called during different stages of processing, but it is close enough. >From a high level view the http module processes request in four stages, parsing requests, check request data, process request data and finally produce a response. This view is valid both the current http code and the new, but it is more cleanly separated now. Previously, members of `struct session_request` required by plugins were set during all stages of processing, but now these are all setup during the processing stage. This will make it very simple to disable the old plugin api, the only thing required is the removal of 4-5 function calls. Until then, monkey will be able to use both old and new plugins seamlessly. ## Static plugin The static file plugin now supports http ranges, does proper path resolution, directory redirect and supports both chunked and fixed size responses. All file handling is done by this plugin, reducing the complexity of the http code. [Code](https://github.com/ksonny/monkey/tree/plugin_next) # Location plugin chains This change adds a new type of section in the vhost, 'Locations'. In these sections you can have two entries, 'Path' and 'Plugins'. Any request where the 'Path' data matches uri path will only be handled by the plugins listed in 'Plugins'. Plugins are matched against their shortname, with 'none' being a special keyword. The plugins listed will be asked to handle the request in the order they are stated, allowing changing plugin priority by configuration. For current monkey master, static files will always be processed for all locations whether there are any plugins registered for that location or not, but with the new plugin api and the addition of the `static` plugin, it is possible to choose if locations should serve static file or not. [Location] Path / Plugins static [Location] Path /protected/ Plugins auth static [Location] Path /disabled/ plugins none The location with the longest matching path prefix will be used, and Plugins are not inherited. [Code](https://github.com/ksonny/monkey/tree/chain_plugin) # Queued file entry with destructor The new plugin api uses a queue with supports for static and heap allocated buffers as well as files. This week I've added support for customizing the file descriptor close functions, allowing it to be excluded or replaced. It allow for the same file descriptors to be used for multiple requests, effectively caching file descriptors. This may not seem like such a great thing, but open() and stat() can be very expensive on some systems. Support is not yet added to the plugin api, but the changes in mk_queue is already in place. [Code](https://github.com/ksonny/monkey/tree/plugin_next) # Plugin event handling Five new functions has been added to the new plugin api for tracking backend file descriptor events. struct sched_connection * mk_event_add(const struct mk_plugin *handler, int fd, int events, void *data); int mk_event_del(struct sched_connection *connection); int mk_event_change(struct sched_conneciton *connection, int events); void * mk_event_data(struct sched_connection *connection); int mk_event_socket(struct sched_connection *connection); Their name and arguments may change but this is their current prototypes. The data argument in `mk_event_add()` can be retrieved using `mk_event_data()`. [Code](https://github.com/ksonny/monkey/tree/plugin_next) # Event sleep/wakeup handling On top of previous week connection hook changes I've implemented an optimization that reduces the complexity of sleep/wakeup of epoll events by reusing the sched_connection structure. The optimization removes one red-black tree lookup by merging it's functionality into a structure tracked by another red-black tree. Currently, a thread local red-black tree keeps mk_epoll_state entries for every connection registered with the worker epoll instance. There also exists another red-black tree with sched_connection entries containing connection hooks, initalization time and some state for all connections registered with the local scheduler. These two trees both uses the socket file descriptor for lookup. This change merges the functionality of mk_epoll_state into a single 32bit field that already exists in sched_connection. While the O complexity of two red-black tree operations is the same as one, it is still an improvement. [Code](https://github.com/ksonny/monkey/tree/event_sleep) [Github](https://github.com/ksonny/) [Blog](https://lotrax.org/gsoc/gsoc-2013-status-future-protocols-week-5.html) -- Sonny Karlsson _______________________________________________ Monkey mailing list [email protected] http://lists.monkey-project.com/listinfo/monkey
