Супер!Еще бы теперь научить nginx кешировать соответствия uri-filename, вслучае
возврата x-accel-redirect, чтобы каждый раз не лазить набекэнд.
On 12/23/05, Dmitriy MiksIr <miksir@xxxxxxxx> wrote:> В таком случае к
тестированию предлагаю модуль =)> Идея модуля такова - но становится
обработчиком */* запросов. Апач> вызывает этот хендлер только если не было
никаких других обработок его,> т.е. имеем то, что нам надо - выдачу голого
файла.> В этом случае модуль выдает X-Accel-Redirect без тела самого файла>
(устанавливая Content-Length: 0)>> Переданный X-Accel-Redirect состоит из двух
частей - строки, принятой от> вронтенда в заголовке X-Accel-Internal и
собственно URI.> Таким образом конфиг nginx выгладит приблизительно так:>>
server {> listen 81;> server_name www;>>
location / {> proxy_pass http://127.0.0.1:80;>
proxy_set_header X-Real-IP $remote_addr;> proxy_set_header
X-Accel-Internal /internal_843t;> proxy_set_header Host
$http_host;> proxy_redirect_errors on;> }>>
location /internal_843t/ {> root /path/to/htdocs/;>
rewrite ^/internal_843t/(.*)$ /$1 break;>
index index.html index.htm;> internal;> }>
}>> Модуль, собственно, умеет 2 директивы>> AccelRedirectSet [On|Off]>
Включение модуля> AccelRedirectSize number[k|M]> Установка
минимального размера запрашиваемого файла, начиная с> которого будут выдаваться
редиректы> Контенты обоих директив: server config, virtual host,
directory>> Установка в апач, конечно же> /usr/local/apache/bin/apxs -c
mod_aclr.c> /usr/local/apache/bin/apxs -i mod_aclr.so> И руками добавить>
LoadModule aclr_module libexec/mod_aclr.so> AddModule mod_aclr.c>> Буду
признателен за любые замечания, как по алгоритму, так и по коду.>>> /*
-------------------------------------------------------------------------- *\>
* mod_aclr.c *>
* Dmitriy MiksIr <miksir@xxxxxxxx>
*> *
*> * Description FIX IT
*> *
*> * This program is free software; you can redistribute it and/or
*> * modify it under the terms of the GNU General Public License
*> * as published by the Free Software Foundation; either version 2
*> * of the License, or (at your option) any later version.
*> *
*> * This program is distributed in the hope that it will be useful,
*> * but WITHOUT ANY WARRANTY; without even the implied warranty of
*> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*> * GNU General Public License for more details.
*> *
*> * You should have received a copy of the GNU General Public
License *> * along with this program; if not, write to the Free
Software *> * Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.*> \*
-------------------------------------------------------------------------- */>>
/*> $Id: mod_aclr.c,v 1.1 2005/12/23 14:05:06 cvs Exp $> */>> #include
"httpd.h"> #include "http_config.h"> #include "http_request.h"> #include
"http_protocol.h"> #include "http_core.h"> #include "http_main.h"> #include
"http_log.h">> module aclr_module;>> #define ACLR_VERSION "0.01">> #define
ACLR_ENABLED 1> #define ACLR_DISABLED 0> #define UNSET -1>> typedef struct {>
int state;> long long fsize;> } aclr_dir_config;>> /*
----------------------------------------- */>> long long parse_bytes(const char
*arg) {> long long ret;> int arglen = strlen(arg);> char last_char =
arg[arglen - 1];> int i;> char arg1[256];>> if (arglen >= 256)
return(-1);>> if(last_char == 'K' || last_char == 'k'> || last_char ==
'M' || last_char == 'm') {> arglen --;> }>>
snprintf(arg1,sizeof(arg1),"%s",arg);>> for (i=0;i<arglen;i++) {>
if(!isdigit(arg1[i])) return(-1);> }>> if(last_char == 'K' || last_char ==
'k')> return(atoll(arg1) * 1024);>> if(last_char == 'M' || last_char ==
'm')> return(atoll(arg1) * 1048576);>> return(atoll(arg1));> }>> /*
----------------------------------------- */>> static int
aclr_handler(request_rec *r)> {> long long filesize;> int
rc;> const char *idhead;> char iredirect[1024];>
aclr_dir_config *cfg = (aclr_dir_config
*)ap_get_module_config(r->per_dir_config, &aclr_module);>> if(cfg->state !=
ACLR_ENABLED)> return(DECLINED);>> if (idhead =
ap_table_get(r->headers_in, "X-Accel-Internal")) {> if
(strlen(idhead)+strlen(r->uri) >= 1024)> return(DECLINED);>
snprintf(iredirect,sizeof(iredirect),"%s%s",idhead,r->uri);> } else {>
return(DECLINED);> }>> ap_table_set(r->headers_out, "X-ACLR-Version",
ACLR_VERSION);>> if ((rc = ap_discard_request_body(r)) != OK) {> return
rc;> }>> if (r->method_number != M_GET)> return(DECLINED);>> if
(r->finfo.st_mode == 0 || (r->path_info && *r->path_info))>
return(DECLINED);>> filesize = r->finfo.st_size;> if (cfg->fsize != UNSET
&& filesize < cfg->fsize)> return(DECLINED);>>
ap_table_set(r->headers_out, "X-Accel-Redirect", iredirect);>>
ap_update_mtime(r, r->finfo.st_mtime);> if (rc = ap_set_content_length(r,
0))> return rc;> ap_send_http_header(r);>> return OK;> }>> /*
------------------------------------------ */>> static void
*aclr_create_dir_config(pool *p, char *path) {> aclr_dir_config *cfg =
(aclr_dir_config *)ap_palloc(p, sizeof(aclr_dir_config));> cfg->state =
UNSET;> cfg->fsize = UNSET;> return( (void *)cfg );> }>> /*
------------------------------------------ */>> static const char
*aclr_cmd_state(cmd_parms *parms, void *mconfig, int flag) {> aclr_dir_config
*cfg = (aclr_dir_config *)mconfig;> cfg->state = (flag ? ACLR_ENABLED :
ACLR_DISABLED);> return(NULL);> }>> static const char
*aclr_cmd_size(cmd_parms *parms, void *mconfig, const char *arg) {>
aclr_dir_config *cfg = (aclr_dir_config *)mconfig;> long long bytes =
parse_bytes(arg);>> if (bytes >= 0) {> cfg->fsize = bytes;> } else {>
cfg->fsize = UNSET;> ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO,
parms->server, "Argument %s of AccelRedirectSize is not number", arg);> }>>
return(NULL);> }>> static const command_rec aclr_cmds[] = {> {
"AccelRedirectSet", aclr_cmd_state, NULL, ACCESS_CONF | RSRC_CONF, FLAG,>
"turn X-Accel-Redirect support On or Off (default Off)" },> {
"AccelRedirectSize", aclr_cmd_size, NULL, ACCESS_CONF | RSRC_CONF, TAKE1,>
"minimum size of file for redirect in bytes" },> { NULL }> };>> /*
------------------------------------------- */>> static const handler_rec
aclr_handlers[] = {> { "*/*", aclr_handler },> { NULL }> };>>
module MODULE_VAR_EXPORT aclr_module = {> STANDARD_MODULE_STUFF,> NULL,
/* module initializer */>
aclr_create_dir_config, /* create per-dir config structures */> NULL,
/* merge per-dir config structures */> NULL,
/* create per-server config structures */> NULL,
/* merge per-server config structures */> aclr_cmds,
/* table of config file commands */> aclr_handlers, /*
[#8] MIME-typed-dispatched handlers */> NULL, /* [#1]
URI to filename translation */> NULL, /* [#4]
validate user id from request */> NULL, /* [#5] check
if the user is ok _here_ */> NULL, /* [#3] check access
by host address */> NULL, /* [#6] determine MIME type
*/> NULL, /* [#7] pre-run fixups
*/> NULL, /* [#9] log a transaction
*/> NULL, /* [#2] header parser */>
NULL, /* child_init */> NULL,
/* child_exit */> NULL
/* [#0] post read-request */> };>>>
--Alexey Polyakov