我想写一个模块,提供一个巨大的虚拟.wav文件(还计划将来添加一个虚拟的.ogg文件)。
我知道文件的大小(2Gb)及其假修改时间(2000-01-01 0:00:00
),我有一个函数来读取文件的一部分:
void virtwav_read(void *buf, ssize_t bufsz, uint32_t virtofs);
我想挂钩低级文件操作,如stat
,read
,seek
等。标准的apache代码应该解析头文件(包括范围请求,与缓存相关的内容)并生成Content-Type
,Content-Length
,ETag,Last-Modified
等。
解析request_rec.range
并不是什么大问题。让我更担心的是在适当的时候发送正确的缓存相关标头和HTTP 206和304。我确信apache会比我的代码更好。
我认为设置request_rec.mtime
和request_rec.clength
可以解决问题,但它们似乎不是输出字段。
最后,VFS是一个令人惊讶的不受欢迎的话题。我发现2003年只有一个古老项目http://apvfs.sourceforge.net/。
这是我的最小模块及其配置。权限Content-Type
由apache添加,但没有ETag
LoadModule virtwav_module modules/mod_virtwav.so
AddHandler virtwav-handler .wav
_
#include "apr_hash.h"
#include "ap_config.h"
#include "ap_provider.h"
#include "httpd.h"
#include "http_core.h"
#include "http_config.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include <unistd.h> /* for sleep() */
static int example_handler(request_rec *r)
{
if (!r->handler || strcmp(r->handler, "virtwav-handler")) return (DECLINED);
//r->clength = 42;
//r->mtime = apr_time_now();
ap_rprintf(r, "clength: %" APR_INT64_T_FMT "\n", (apr_int64_t)r->clength);
ap_rprintf(r, "mtime: %" APR_INT64_T_FMT "\n", (apr_int64_t)r->mtime);
ap_rwrite("dummy", 5, r);
ap_rflush(r);
sleep(50);
return OK;
}
static void register_hooks(apr_pool_t *pool)
{
/* Create a hook in the request handler, so we get called when a request arrives */
ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
// ap_hook_dirwalk_stat ?
// This hook allows modules to handle/emulate the apr_stat()
// ap_hook_map_to_storage ?
// This hook allow modules to set the per_dir_config based on their own
}
module AP_MODULE_DECLARE_DATA virtwav_module =
{
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
register_hooks /* Our hook registering function */
};