/******************************************************************************************************************
Discription: This is a simple memcached module for Apache web server, which can set a picture file into memcached.
*******************************************************************************************************************
made by Reesun Huang at 2010.04
*******************************************************************************************************************
Version: 0.1
******************************************************************************************************************/
#include <httpd.h>
#include <http_protocol.h>
#include <http_config.h>
#include <http_log.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <libmemcached/memcached.h>
//该函数用于设定memcached的key值
char * location(request_rec *r)
{
char *key;
key = (char *)rindex(r->uri, '/');
if (key)
return key;
else
return NULL;
}
static int memcached_handler(request_rec *r)
{
memcached_st *memc;
memcached_return rc;
memcached_server_st *servers;
char bytebuf[r->finfo.size];
char *fileName = NULL;
FILE *fp = NULL;
apr_file_t *fd;
apr_size_t sz;
apr_status_t rv;
//判断头部,如果头部不是“memcached”则返回。
if (!r->handler || strcmp(r->handler, "memcached")) {
return DECLINED;
}
//判断文件名是否为空,如为空则返回
if (r->filename == NULL) {
return DECLINED;
}
//从文件信息中获取一些有用的头文件定义内容
if(r->finfo.mtime){
char *datestring = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
apr_rfc822_date(datestring, r->finfo.mtime);
apr_table_setn(r->headers_out, "Last-Modified", datestring);
}
/***************************************************************************************************************
定义memcached的key值,其值为“/$memcached_key”。其中“$memcached_key”为nginx传递给Apache的key值
***************************************************************************************************************/
fileName = location(r);
//将文件转化为byte数组
fp = fopen(r->filename, "rb");
if(!fread(bytebuf, 1, r->finfo.size, fp)) {
return DECLINED;
}
fclose(fp);
//将相应文件写入memcached缓存
//连接memcached服务器
memc = memcached_create(NULL);
servers = memcached_server_list_append(NULL, "localhost", 12000, &rc);
rc = memcached_server_push(memc, servers);
memcached_server_free(servers);
//将相应文件写入memcached缓存
rc = memcached_set(memc, fileName, strlen(fileName), bytebuf, sizeof(bytebuf), (time_t)0, (uint32_t)0);
if(rc != MEMCACHED_SUCCESS){
return DECLINED;
}//fi
//断开连接
memcached_free(memc);
//写入缓存后,将相应文件输出。这样在html文件嵌入的图片就能输出了
rv = apr_file_open(&fd, r->filename,
APR_READ|APR_SHARELOCK|APR_SENDFILE_ENABLED,
APR_OS_DEFAULT, r->pool);
if(rv != APR_SUCCESS){
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"can't open %s", r->filename);
return HTTP_NOT_FOUND;
}
ap_send_fd (fd, r, 0, r->finfo.size, &sz);
apr_file_close (fd);
return OK;
}
static void memcached_hooks(apr_pool_t *pool)
{
ap_hook_handler(memcached_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA memcached_module = {
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
memcached_hooks
};
|