/** * mod_range_limit * --------------- * Limit the number of range-requests per connection * * Configuration: * RangeLimit {On|Off} Enable/Disable usage of module, works per vhost * RangeCount {int} Set the maximum number of range-requests, works per vhost * * * Author: Bernd Holzmueller * Contributions by: Jan Philipp Guenther * * License: Creative Commons Attribution-Share Alike 3.0 Germany * http://creativecommons.org/licenses/by-sa/3.0/de/ * * Copyright (C) tiggersWelt.net, 2011 **/ #include "httpd.h" #include "http_config.h" #include "http_core.h" #include "http_log.h" #include "http_protocol.h" #include "http_vhost.h" #include "apr_strings.h" module AP_MODULE_DECLARE_DATA range_limit_module; typedef struct { int enable; int count; } range_limit_server_cfg; void *range_limit_create_dir_cfg (apr_pool_t *p, char *dummy) { range_limit_server_cfg *cfg = (range_limit_server_cfg *)apr_pcalloc (p, sizeof(range_limit_server_cfg)); if (!cfg) return NULL; cfg->enable = 0; cfg->count = 0; return (void *)cfg; } static const char *range_limit_enable (cmd_parms *cmd, void *config, int flag) { server_rec *s = cmd->server; range_limit_server_cfg *cfg = (range_limit_server_cfg *)config; if (!cfg) return NULL; cfg->enable = flag; return NULL; } static const char *range_limit_counter (cmd_parms *cmd, void *config, const char *arg) { server_rec *s = cmd->server; range_limit_server_cfg *cfg = (range_limit_server_cfg *)config; if (!cfg) return NULL; cfg->count = atol (arg); return NULL; } static int range_limit (request_rec *r) { range_limit_server_cfg *cfg = (range_limit_server_cfg *)ap_get_module_config (r->per_dir_config, &range_limit_module); const char *range; int counter = 0; if (!cfg) return DECLINED; if (!cfg->enable || !cfg->count) return DECLINED; if (!(range = apr_table_get(r->headers_in, "Range"))) if (!(range = apr_table_get(r->headers_in, "Request-Range"))) return DECLINED; for (; *range; range++) if ((*range == ',') && (++counter > cfg->count)) return HTTP_RANGE_NOT_SATISFIABLE; return DECLINED; } static const command_rec range_limit_cmds[] = { AP_INIT_FLAG ( "RangeLimit", range_limit_enable, NULL, RSRC_CONF, "Enable Limits for Range-Headers" ), AP_INIT_TAKE1 ( "RangeCount", range_limit_counter, NULL, RSRC_CONF, "Set the maximum number of range chunks per request" ), { NULL } }; static void register_hooks(apr_pool_t *p) { ap_hook_post_read_request (range_limit, NULL, NULL, APR_HOOK_FIRST); } module AP_MODULE_DECLARE_DATA range_limit_module = { STANDARD20_MODULE_STUFF, range_limit_create_dir_cfg, NULL, NULL, NULL, range_limit_cmds, register_hooks, };