I want to write a module that serves a huge virtual .wav file (also plan to add a virtual .ogg file in the future).
I know the size of the file (2Gb) and its fake modification time (2000-01-01 0:00:00
) and I have a function to read portion of the file:
void virtwav_read(void *buf, ssize_t bufsz, uint32_t virtofs);
I want to hook the low-level file operations like stat
, read
, seek
, etc. The standard apache code should take care of parsing the headers (including range requests, cache-related stuff) and generate Content-Type
, Content-Length
, ETag, Last-Modified
, etc.
Parsing the request_rec.range
is not a big deal. What worries me more is sending the right cache-related headers and HTTP 206 and 304 when approprate. I'm sure apache would do that better than my code.
I thought that setting request_rec.mtime
and request_rec.clength
would do the trick, but they don't seem to be output fields.
Lastly, VFS is surprisingly unpopular topic. I found only one ancient project http://apvfs.sourceforge.net/ dated 2003.
Here's my minimal module and its config. The right Content-Type
is added by apache, but no 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 */
};