论坛首页 编程语言技术论坛

Apache模块-下载文件-性能测试打靶用的靶子

浏览 2582 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-12-16   最后修改:2010-12-17
C

apache模块,

下载某一个文件,

性能测试打靶用,

当靶子。

 

/* 
**  mod_preview.c -- Apache sample preview module
**  [Autogenerated via ``apxs -n preview -g'']
**
**  To play with this sample module first compile it into a
**  DSO file and install it into Apache's modules directory 
**  by running:
**
**    $ apxs -c -i mod_preview.c
**
**  Then activate it in Apache's httpd.conf file for instance
**  for the URL /preview in as follows:
**
**    #   httpd.conf
**    LoadModule preview_module modules/mod_preview.so
**    <Location /preview>
**    SetHandler preview
**    </Location>
**
**  Then after restarting Apache via
**
**    $ apachectl restart
**
**  you immediately can request the URL /preview and watch for the
**  output of this module. This can be achieved for instance via:
**
**    $ lynx -mime_header http://localhost/preview 
**
**  The output should be similar to the following one:
**
**    HTTP/1.1 200 OK
**    Date: Tue, 31 Mar 1998 14:42:22 GMT
**    Server: Apache/1.3.4 (Unix)
**    Connection: close
**    Content-Type: text/html
**  
**    The page from mod_preview.c
*/ 

#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
#include "ap_regex.h"
#include "http_log.h"

/* The content handler */
static int preview_handler(request_rec *r)
{
	char *fn;// = "/usr/local/httpd-2.3.8/include/httpd.h";
	apr_file_t *f = NULL;
	apr_status_t rv;
	apr_size_t sz;

	ap_regex_t *preg;
	const char *regex = "filename=([^\\&]*)(.*)";
	int regRet = AP_REG_NOMATCH;
	int nmatch = AP_MAX_REG_MATCH;
	ap_regmatch_t pmatch[nmatch];

	if(strlen(r->args) == 0){
		ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL,r->server,"No args.");
		return HTTP_INTERNAL_SERVER_ERROR;
	}else{
		if(ap_regcomp(preg,regex,0) == 0){
			regRet = ap_regexec(preg,r->args,nmatch,pmatch,AP_REG_EXTENDED|AP_REG_ICASE);
			ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL,r->server,"Compile a regular expression. %s",regex);
		}
		else{
			ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL,r->server," Compile regular expression fail.");
			ap_rputs("ap_regexec error.",r);
			return DONE;
		}

		if(regRet == 0){
			fn = (char *)calloc(pmatch[1].rm_eo - pmatch[1].rm_so + 1,sizeof(char));
			memcpy(fn,r->args+pmatch[1].rm_so,pmatch[1].rm_eo - pmatch[1].rm_so);
			rv = apr_file_open(&f,fn,APR_READ|APR_SENDFILE_ENABLED,APR_OS_DEFAULT,r->pool);
			ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL,r->server,"Get matched parameter : %s",fn);
			ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL,r->server,"File open status : %d",rv);
		}else{
			ap_rprintf(r,"Reguler Expression is not matched %s.\n",r->args);
			ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL,r->server,"Reguler Expression is not matched.");
			return DONE;
		}
	}

	if (strcmp(r->handler, "preview")) {
		return DECLINED;
	}
	r->content_type = "text/html";

	if (!r->header_only){
			if(rv == APR_SUCCESS){
				apr_finfo_t info;
				apr_stat(&info,fn,APR_FINFO_SIZE,r->pool);
				apr_size_t size = (apr_size_t)info.size;
				if (APR_SUCCESS != ap_send_fd(f, r, 0, size, &sz)) {
					return HTTP_INTERNAL_SERVER_ERROR;
				}
				apr_off_t fpos = sz;

				while (1) {
					/* flush output first */
					ap_flush_conn(r->connection);
					if (fpos < size) {
						/* file grew by finfo.size - fpos */
						if (APR_SUCCESS != ap_send_fd(f, r, fpos, size - fpos, &sz)) {
							return HTTP_INTERNAL_SERVER_ERROR;
						}
						fpos += sz;
					} else {
						break;
					}
				}
			apr_file_close(f);
			return OK;
		}else{
			ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL,r->server,"Open %s error!\n args : %s\n", fn,r->args);
			return DONE;
		}
	}
	return OK;
}

static void preview_register_hooks(apr_pool_t *p)
{
    ap_hook_handler(preview_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA preview_module = {
    STANDARD20_MODULE_STUFF, 
    NULL,                  /* create per-dir    config structures */
    NULL,                  /* merge  per-dir    config structures */
    NULL,                  /* create per-server config structures */
    NULL,                  /* merge  per-server config structures */
    NULL,                  /* table of config file commands       */
    preview_register_hooks  /* register hooks                      */
};

 

 

编译:

apxs -c mod_preview.c

 

安装:

apxs -ia mod_preview.la

 

配置:

vim httpd.conf

 

添加:

<Location /preview>
        SetHandler preview
</Location>

 

注意apache进程的用户权限和被访问文件的权限

 

URL参数:

const char *regex = "filename=([^\\&]*)(.*)";

正则扣取filename后面的文件绝对路径。

   发表时间:2011-01-04  

问题一:
配置文件中:SetHandler后面的字符串,
也就是
if (strcmp(r->handler, "preview"))中的preview
这个字符串的长度有限制,太长的话模块不起作用。

问题二:
#     if (strcmp(r->handler, "preview")) { 
#         return DECLINED; 
#     }
这个要写在执行代码的最前面,否则每个请求都过来执行一下,然后运行到这步发现进错模块了。我上面写的不好。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics