예제 #1
0
static vod_status_t
segmenter_init_adaptations_config(segmenter_conf_t* conf, vod_pool_t* pool)
{
	vod_array_t  **tmp_list, *adaptation_list;
	vod_status_t   rc;
	vod_int_t      n, i;

	tmp_list = conf->adaptation_durations->elts;
	n = conf->adaptation_durations->nelts;

	if (n == 1)
	{
		adaptation_list = vod_alloc(pool, sizeof(vod_array_t));
		if (adaptation_list == NULL)
		{
			return VOD_ALLOC_FAILED;
		}

		*adaptation_list = *tmp_list[0];
		rc = segmenter_adaptation_durations_to_conf(conf, adaptation_list);
		if (rc != VOD_OK)
		{
			return rc;
		}

		return VOD_AGAIN;
	}

	conf->adaptation_configs = vod_alloc(pool, n * sizeof(segmenter_conf_t));

	for (i = 0; i < n; i++)
	{
		adaptation_list = vod_alloc(pool, sizeof(vod_array_t));
		if (adaptation_list == NULL)
		{
			return VOD_ALLOC_FAILED;
		}

		*adaptation_list = *tmp_list[i];
		rc = segmenter_adaptation_durations_to_conf(&conf->adaptation_configs[i], adaptation_list);
		if (rc != VOD_OK)
		{
			return rc;
		}

		conf->adaptation_configs[i].align_to_key_frames = conf->align_to_key_frames;
		conf->adaptation_configs[i].live_segment_count = conf->live_segment_count;
		conf->adaptation_configs[i].get_segment_count = conf->get_segment_count;
		conf->adaptation_configs[i].get_segment_durations = conf->get_segment_durations;

		rc = segmenter_init_config(&conf->adaptation_configs[i], pool);
		if (rc != VOD_OK)
		{
			return rc;
		}
	}

	return VOD_OK;
}
예제 #2
0
static char *
ngx_http_vod_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
    ngx_http_vod_loc_conf_t *prev = parent;
    ngx_http_vod_loc_conf_t *conf = child;
	const ngx_http_vod_submodule_t** cur_module;
	ngx_int_t rc;
	size_t proxy_header_len;
	u_char* p;
	char* err;

	// base params
	ngx_conf_merge_str_value(conf->child_request_location, prev->child_request_location, "");
	if (conf->submodule.parse_uri_file_name == NGX_CONF_UNSET_PTR) 
	{
		if (prev->submodule.parse_uri_file_name != NGX_CONF_UNSET_PTR)
		{
			conf->submodule = prev->submodule;
		}
		else
		{
			// zero module = serve files
			ngx_memzero(&conf->submodule, sizeof(conf->submodule));
		}
	}
	ngx_conf_merge_ptr_value(conf->request_handler, prev->request_handler, ngx_http_vod_local_request_handler);
	ngx_conf_merge_str_value(conf->multi_uri_suffix, prev->multi_uri_suffix, ".urlset");

	ngx_conf_merge_uint_value(conf->segmenter.segment_duration, prev->segmenter.segment_duration, 10000);
	ngx_conf_merge_ptr_value(conf->segmenter.bootstrap_segments, prev->segmenter.bootstrap_segments, NULL);
	ngx_conf_merge_value(conf->segmenter.align_to_key_frames, prev->segmenter.align_to_key_frames, 0);
	ngx_conf_merge_ptr_value(conf->segmenter.get_segment_count, prev->segmenter.get_segment_count, segmenter_get_segment_count_last_short);
	ngx_conf_merge_ptr_value(conf->segmenter.get_segment_durations, prev->segmenter.get_segment_durations, segmenter_get_segment_durations_estimate);

	if (conf->secret_key == NULL) 
	{
		conf->secret_key = prev->secret_key;
	}
	ngx_conf_merge_uint_value(conf->duplicate_bitrate_threshold, prev->duplicate_bitrate_threshold, 4096);
	ngx_conf_merge_str_value(conf->https_header_name, prev->https_header_name, "");
	ngx_conf_merge_str_value(conf->segments_base_url, prev->segments_base_url, "");
	conf->segments_base_url_has_scheme =
		(ngx_strncasecmp(conf->segments_base_url.data, (u_char *) "http://", 7) == 0 ||
		ngx_strncasecmp(conf->segments_base_url.data, (u_char *) "https://", 8) == 0);


	if (conf->moov_cache_zone == NULL) 
	{
		conf->moov_cache_zone = prev->moov_cache_zone;
	}

	if (conf->response_cache_zone == NULL)
	{
		conf->response_cache_zone = prev->response_cache_zone;
	}
	
	ngx_conf_merge_size_value(conf->initial_read_size, prev->initial_read_size, 4096);
	ngx_conf_merge_size_value(conf->max_moov_size, prev->max_moov_size, 128 * 1024 * 1024);
	ngx_conf_merge_size_value(conf->cache_buffer_size, prev->cache_buffer_size, 256 * 1024);

	err = ngx_merge_upstream_conf(cf, &conf->upstream, &prev->upstream);
	if (err != NGX_CONF_OK)
	{
		ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
			"ngx_http_vod_merge_loc_conf: ngx_merge_upstream_conf failed (1)");
		return err;
	}
	ngx_conf_merge_str_value(conf->upstream_host_header, prev->upstream_host_header, "");
	
	if (conf->upstream_extra_args == NULL) 
	{
		conf->upstream_extra_args = prev->upstream_extra_args;
	}

	if (conf->path_mapping_cache_zone == NULL)
	{
		conf->path_mapping_cache_zone = prev->path_mapping_cache_zone;
	}
	ngx_conf_merge_str_value(conf->path_response_prefix, prev->path_response_prefix, "<?xml version=\"1.0\" encoding=\"utf-8\"?><xml><result>");
	ngx_conf_merge_str_value(conf->path_response_postfix, prev->path_response_postfix, "</result></xml>");
	ngx_conf_merge_size_value(conf->max_path_length, prev->max_path_length, 1024);

	err = ngx_merge_upstream_conf(cf, &conf->fallback_upstream, &prev->fallback_upstream);
	if (err != NGX_CONF_OK)
	{
		ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
			"ngx_http_vod_merge_loc_conf: ngx_merge_upstream_conf failed (2)");
		return err;
	}
	ngx_conf_merge_str_value(conf->proxy_header_name, prev->proxy_header_name, "X-Kaltura-Proxy");
	ngx_conf_merge_str_value(conf->proxy_header_value, prev->proxy_header_value, "dumpApiRequest");

	ngx_conf_merge_value(conf->last_modified_time, prev->last_modified_time, -1);
	if (ngx_http_merge_types(
		cf, 
		&conf->last_modified_types_keys, 
		&conf->last_modified_types,
		&prev->last_modified_types_keys, 
		&prev->last_modified_types,
		ngx_http_vod_last_modified_default_types) != NGX_OK)
	{
		return NGX_CONF_ERROR;
	}

	ngx_conf_merge_value(conf->drm_enabled, prev->drm_enabled, 0);
	ngx_conf_merge_uint_value(conf->drm_clear_lead_segment_count, prev->drm_clear_lead_segment_count, 1);
	err = ngx_merge_upstream_conf(cf, &conf->drm_upstream, &prev->drm_upstream);
	if (err != NGX_CONF_OK)
	{
		ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
			"ngx_http_vod_merge_loc_conf: ngx_merge_upstream_conf failed (3)");
		return err;
	}
	ngx_conf_merge_size_value(conf->drm_max_info_length, prev->drm_max_info_length, 4096);
	if (conf->drm_info_cache_zone == NULL)
	{
		conf->drm_info_cache_zone = prev->drm_info_cache_zone;
	}
	if (conf->drm_request_uri == NULL) 
	{
		conf->drm_request_uri = prev->drm_request_uri;
	}

	ngx_conf_merge_str_value(conf->clip_to_param_name, prev->clip_to_param_name, "clipTo");
	ngx_conf_merge_str_value(conf->clip_from_param_name, prev->clip_from_param_name, "clipFrom");
	ngx_conf_merge_str_value(conf->tracks_param_name, prev->tracks_param_name, "tracks");
	ngx_conf_merge_str_value(conf->speed_param_name, prev->speed_param_name, "speed");

	if (conf->perf_counters_zone == NULL)
	{
		conf->perf_counters_zone = prev->perf_counters_zone;
	}

#if (NGX_THREADS)
	ngx_conf_merge_ptr_value(conf->open_file_thread_pool, prev->open_file_thread_pool, NULL);
#endif

	// validate vod_upstream / vod_upstream_host_header used when needed
	if (conf->request_handler == ngx_http_vod_remote_request_handler || conf->request_handler == ngx_http_vod_mapped_request_handler)
	{
		if (conf->child_request_location.len == 0)
		{
			ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
				"\"vod_child_request_path\" is mandatory for remote/mapped modes");
			return NGX_CONF_ERROR;
		}

		if (conf->upstream.upstream == NULL)
		{
			ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
				"\"vod_upstream\" is mandatory for remote/mapped modes");
			return NGX_CONF_ERROR;
		}
	}
	else
	{
		if (conf->upstream.upstream != NULL)
		{
			ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
				"\"vod_upstream\" does not apply to local mode");
			return NGX_CONF_ERROR;
		}

		if (conf->upstream_host_header.len != 0)
		{
			ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
				"\"vod_upstream_host_header\" does not apply to local mode");
			return NGX_CONF_ERROR;
		}
	}
	
	if (conf->request_handler == ngx_http_vod_remote_request_handler)
	{
		if (conf->fallback_upstream.upstream != NULL)
		{
			ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
				"\"vod_fallback_upstream\" does not apply to remote mode");
			return NGX_CONF_ERROR;
		}
	}

	if (conf->segmenter.segment_duration <= 0)
	{
		ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
			"\"segment_duration\" must be positive");
		return NGX_CONF_ERROR;
	}

	rc = segmenter_init_config(&conf->segmenter, cf->pool);
	if (rc != VOD_OK)
	{
		ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
			"failed to initialize the segmenter %i", rc);
		return NGX_CONF_ERROR;
	}

	if (conf->drm_enabled && conf->drm_upstream.upstream == NULL)
	{
		ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
			"\"drm_upstream\" must be configured when drm is enabled");
		return NGX_CONF_ERROR;
	}

	// validate the lengths of uri parameters
	if (conf->clip_to_param_name.len > MAX_URI_PARAM_NAME_LEN)
	{
		ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
			"\"clip_to_param_name\" should not be more than %d characters", MAX_URI_PARAM_NAME_LEN);
		return NGX_CONF_ERROR;
	}

	if (conf->clip_from_param_name.len > MAX_URI_PARAM_NAME_LEN)
	{
		ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
			"\"clip_from_param_name\" should not be more than %d characters", MAX_URI_PARAM_NAME_LEN);
		return NGX_CONF_ERROR;
	}

	if (conf->tracks_param_name.len > MAX_URI_PARAM_NAME_LEN)
	{
		ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
			"\"tracks_param_name\" should not be more than %d characters", MAX_URI_PARAM_NAME_LEN);
		return NGX_CONF_ERROR;
	}

	if (conf->speed_param_name.len > MAX_URI_PARAM_NAME_LEN)
	{
		ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
			"\"speed_param_name\" should not be more than %d characters", MAX_URI_PARAM_NAME_LEN);
		return NGX_CONF_ERROR;
	}
	
	// combine the proxy header name and value to a single line
	proxy_header_len = conf->proxy_header_name.len + sizeof(": ") - 1 + conf->proxy_header_value.len + sizeof(CRLF);
	conf->proxy_header.data = ngx_palloc(cf->pool, proxy_header_len);
	if (conf->proxy_header.data == NULL)
	{
		return NGX_CONF_ERROR;
	}
	p = conf->proxy_header.data;
	p = ngx_copy(p, conf->proxy_header_name.data, conf->proxy_header_name.len);
	*p++ = ':';		*p++ = ' ';
	p = ngx_copy(p, conf->proxy_header_value.data, conf->proxy_header_value.len);
	*p++ = '\r';		*p++ = '\n';
	*p = '\0';

	conf->proxy_header.len = p - conf->proxy_header.data;

	// init the hash table of the uri params (clipTo, clipFrom etc.)
	rc = ngx_http_vod_init_uri_params_hash(cf, conf);
	if (rc != NGX_OK)
	{
		ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
			"ngx_http_vod_merge_loc_conf: ngx_http_vod_init_uri_params_hash failed");
		return NGX_CONF_ERROR;
	}

	// merge the submodules configuration
	for (cur_module = submodules; *cur_module != NULL; cur_module++)
	{
		err = (*cur_module)->merge_loc_conf(
			cf, 
			conf, 
			(u_char*)conf + (*cur_module)->conf_offset, 
			(u_char*)prev + (*cur_module)->conf_offset);
		if (err != NGX_CONF_OK)
		{
			ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
				"ngx_http_vod_merge_loc_conf: submodule merge_loc_conf failed");
			return err;
		}
	}

    return NGX_CONF_OK;
}