diff options
Diffstat (limited to 'src/mod_flv_streaming.c')
-rw-r--r-- | src/mod_flv_streaming.c | 322 |
1 files changed, 0 insertions, 322 deletions
diff --git a/src/mod_flv_streaming.c b/src/mod_flv_streaming.c deleted file mode 100644 index b527ad58..00000000 --- a/src/mod_flv_streaming.c +++ /dev/null @@ -1,322 +0,0 @@ -#include <ctype.h> -#include <stdlib.h> -#include <string.h> - -#include "base.h" -#include "log.h" -#include "buffer.h" -#include "response.h" -#include "stat_cache.h" - -#include "plugin.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* plugin config for all request/connections */ - -typedef struct { - array *extensions; -} plugin_config; - -typedef struct { - PLUGIN_DATA; - - buffer *query_str; - array *get_params; - - plugin_config **config_storage; - - plugin_config conf; -} plugin_data; - -/* init the plugin data */ -INIT_FUNC(mod_flv_streaming_init) { - plugin_data *p; - - UNUSED(srv); - - p = calloc(1, sizeof(*p)); - - p->query_str = buffer_init(); - p->get_params = array_init(); - - return p; -} - -/* detroy the plugin data */ -FREE_FUNC(mod_flv_streaming_free) { - plugin_data *p = p_d; - - UNUSED(srv); - - if (!p) return HANDLER_GO_ON; - - if (p->config_storage) { - size_t i; - - for (i = 0; i < srv->config_context->used; i++) { - plugin_config *s = p->config_storage[i]; - - if (!s) continue; - - array_free(s->extensions); - - free(s); - } - free(p->config_storage); - } - - buffer_free(p->query_str); - array_free(p->get_params); - - free(p); - - return HANDLER_GO_ON; -} - -/* handle plugin config and check values */ - -SETDEFAULTS_FUNC(mod_flv_streaming_set_defaults) { - plugin_data *p = p_d; - size_t i = 0; - - config_values_t cv[] = { - { "flv-streaming.extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */ - { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } - }; - - if (!p) return HANDLER_ERROR; - - p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); - - for (i = 0; i < srv->config_context->used; i++) { - plugin_config *s; - - s = calloc(1, sizeof(plugin_config)); - s->extensions = array_init(); - - cv[0].destination = s->extensions; - - p->config_storage[i] = s; - - if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { - return HANDLER_ERROR; - } - } - - return HANDLER_GO_ON; -} - -static int mod_flv_streaming_patch_connection(server *srv, connection *con, plugin_data *p) { - size_t i, j; - plugin_config *s = p->config_storage[0]; - - PATCH_OPTION(extensions); - - /* skip the first, the global context */ - for (i = 1; i < srv->config_context->used; i++) { - data_config *dc = (data_config *)srv->config_context->data[i]; - s = p->config_storage[i]; - - /* condition didn't match */ - if (!config_check_cond(srv, con, dc)) continue; - - /* merge config */ - for (j = 0; j < dc->value->used; j++) { - data_unset *du = dc->value->data[j]; - - if (buffer_is_equal_string(du->key, CONST_STR_LEN("flv-streaming.extensions"))) { - PATCH_OPTION(extensions); - } - } - } - - return 0; -} - -static int split_get_params(array *get_params, buffer *qrystr) { - size_t is_key = 1; - size_t i; - char *key = NULL, *val = NULL; - - key = qrystr->ptr; - - /* we need the \0 */ - for (i = 0; i < qrystr->used; i++) { - switch(qrystr->ptr[i]) { - case '=': - if (is_key) { - val = qrystr->ptr + i + 1; - - qrystr->ptr[i] = '\0'; - - is_key = 0; - } - - break; - case '&': - case '\0': /* fin symbol */ - if (!is_key) { - data_string *ds; - /* we need at least a = since the last & */ - - /* terminate the value */ - qrystr->ptr[i] = '\0'; - - if (NULL == (ds = (data_string *)array_get_unused_element(get_params, TYPE_STRING))) { - ds = data_string_init(); - } - buffer_copy_string_len(ds->key, key, strlen(key)); - buffer_copy_string_len(ds->value, val, strlen(val)); - - array_insert_unique(get_params, (data_unset *)ds); - } - - key = qrystr->ptr + i + 1; - val = NULL; - is_key = 1; - break; - } - } - - return 0; -} - -/** - * - * @param - */ -URIHANDLER_FUNC(mod_flv_streaming_path_handler) { - plugin_data *p = p_d; - int s_len; - size_t k; - - UNUSED(srv); - - if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON; - - if (con->conf.log_request_handling) { - TRACE("-- handling %s in mod_flv_streaming", SAFE_BUF_STR(con->physical.path)); - } - - mod_flv_streaming_patch_connection(srv, con, p); - - s_len = con->physical.path->used - 1; - - for (k = 0; k < p->conf.extensions->used; k++) { - data_string *ds = (data_string *)p->conf.extensions->data[k]; - int ct_len = ds->value->used - 1; - - if (ct_len > s_len) continue; - if (ds->value->used == 0) continue; - - if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { - data_string *get_param; - stat_cache_entry *sce = NULL; - buffer *b; - long start; - char *err = NULL; - /* if there is a start=[0-9]+ in the header use it as start, - * otherwise send the full file */ - - array_reset(p->get_params); - buffer_copy_string_buffer(p->query_str, con->uri.query); - split_get_params(p->get_params, p->query_str); - - if (NULL == (get_param = (data_string *)array_get_element(p->get_params, CONST_STR_LEN("start")))) { - if (con->conf.log_request_handling) { - TRACE("start=... not found, skipping %s", SAFE_BUF_STR(con->physical.path)); - } - - return HANDLER_GO_ON; - } - - /* too short */ - if (get_param->value->used < 2) { - if (con->conf.log_request_handling) { - TRACE("start=... found, but empty, skipping %s", SAFE_BUF_STR(con->physical.path)); - } - - return HANDLER_GO_ON; - } - - /* check if it is a number */ - start = strtol(get_param->value->ptr, &err, 10); - if (*err != '\0') { - if (con->conf.log_request_handling) { - TRACE("parsing start '%s' as number failed, skipping %s", - SAFE_BUF_STR(get_param->value), SAFE_BUF_STR(con->physical.path)); - } - - return HANDLER_GO_ON; - } - - if (start <= 0) { - if (con->conf.log_request_handling) { - TRACE("start is <= 0, skipping %s", SAFE_BUF_STR(con->physical.path)); - } - - return HANDLER_GO_ON; - } - - /* check if start is > filesize */ - if (HANDLER_GO_ON != stat_cache_get_entry(srv, con, con->physical.path, &sce)) { - if (con->conf.log_request_handling) { - TRACE("stat() for %s failed", SAFE_BUF_STR(con->physical.path)); - } - - return HANDLER_GO_ON; - } - - if (start > sce->st.st_size) { - if (con->conf.log_request_handling) { - TRACE("start > file-size, skipping %s", SAFE_BUF_STR(con->physical.path)); - } - - return HANDLER_GO_ON; - } - - /* we are safe now, let's build a flv header */ - b = chunkqueue_get_append_buffer(con->send); - buffer_copy_string_len(b, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9")); - - chunkqueue_append_file(con->send, con->physical.path, start, sce->st.st_size - start); - - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv")); - - con->send->is_closed = 1; - - if (con->conf.log_request_handling) { - TRACE("sending %s from position %ld", SAFE_BUF_STR(con->physical.path), start); - } - - return HANDLER_FINISHED; - } - } - - if (con->conf.log_request_handling) { - TRACE("none of the extensions matched %s, leaving", SAFE_BUF_STR(con->physical.path)); - } - - /* not found */ - return HANDLER_GO_ON; -} - -/* this function is called at dlopen() time and inits the callbacks */ - -LI_EXPORT int mod_flv_streaming_plugin_init(plugin *p); -LI_EXPORT int mod_flv_streaming_plugin_init(plugin *p) { - p->version = LIGHTTPD_VERSION_ID; - p->name = buffer_init_string("flv_streaming"); - - p->init = mod_flv_streaming_init; - p->handle_physical = mod_flv_streaming_path_handler; - p->set_defaults = mod_flv_streaming_set_defaults; - p->cleanup = mod_flv_streaming_free; - - p->data = NULL; - - return 0; -} |