/*
* Using Nginx subrequest to achieve interaction with multiple backend servers * Nginx version:1.2.2 * Copyright (C) eling * email:luxuejun12@gmai.com * * /extern "C" {#include <ngx_config.h> #include <ngx_core.h> #include <ngx_http.h>}//Nginx header Files should go before other, because they define 64-bit off_t #define LAUTH_EXT_CMD_ARGS_NUM 2 typedef struct {NGX _uint_t N;
2 ngx_array_t *uris;
} ngx_http_lauth_ext_conf_t;
typedef struct {ngx_uint_t done;
ngx_uint_t status;
ngx_str_t *content;
ngx_http_request_t *SR;
} ngx_http_lauth_ext_subrequest;
typedef struct {ngx_uint_t i;
ngx_array_t *subrequests;
} ngx_http_lauth_ext_ctx_t;
Static ngx_int_t Ngx_http_lauth_ext_handler (ngx_http_request_t *r);
Static ngx_int_t Ngx_http_lauth_ext_done (ngx_http_request_t *r, void *data, ngx_int_t RC);
static void *ngx_http_lauth_ext_create_conf (ngx_conf_t *cf); static Char *ngx_http_lauth_ext (ngx_conf_t *CF, ngx_command_t *cmd, void *conf); Static ngx_command_t ngx_http_lauth_ext_commands[] = {{ngx_string ("Lauth_ext"), ngx_http_loc_conf| Ngx_conf_take2, Ngx_http_lauth_ext, Ngx_http_loc_conf_offset, 0, NULL}, Ngx_null_command}
; Static ngx_http_module_t Ngx_http_lauth_ext_module_ctx = {NULL,/* preconfiguration */NULL,/* postconfiguration */NULL,/* Create main Configur ation */NULL,/* INIT main configuration */null, /* Create server Configuration */NULL,/* Merge server configuration */NGX _http_lauth_ext_create_conf,/* Create location Configuration */NULL/* Merge location configuration
*/
}; ngx_module_t Ngx_http_lauth_ext_module = {NGX_MODULE_V1, &ngx_http_lauth_exT_MODULE_CTX,/* Module context */Ngx_http_lauth_ext_commands,/* Module directives */Ngx_http_module ,/* Module type */NULL,/* INIT master */NULL, /* INIT module */NULL,/* INIT process */NULL, /* INIT thread */NULL,/* EXIT thread */NULL, /* Exit Process */NULL,/* Exit Master */NGX_MODULE_V1
_padding}; Static ngx_int_t Ngx_http_lauth_ext_handler (ngx_http_request_t *r) {ngx_log_error (Ngx_log_debug, r->connection-
>log, 0, "Lauth_ext request handler, Uri:%v args:%v", &r->uri, &r->args);
ngx_int_t RC;
ngx_http_lauth_ext_conf_t *LACF;
ngx_str_t *uri;
ngx_str_t *args;
ngx_http_lauth_ext_ctx_t *ctx; Ngx_http_lauth_ext_subrequest *lasr;
ngx_http_post_subrequest_t *ps;
LACF = (ngx_http_lauth_ext_conf_t *) ngx_http_get_module_loc_conf (R, Ngx_http_lauth_ext_module);
CTX = (ngx_http_lauth_ext_ctx_t *) Ngx_http_get_module_ctx (R, Ngx_http_lauth_ext_module);
args = &r->args; if (ctx! = NULL) {ngx_http_lauth_ext_subrequest* Lasr = (ngx_http_lauth_ext_subrequest*) Ctx->subrequests->elts +
(ctx->i-1); if (ctx->i = = Lauth_ext_cmd_args_num) {if (Lasr->status = = ngx_http_internal_server_error) {Ngx_http_finalize_r
Equest (R, Ngx_http_internal_server_error);
return NGX_OK;
} else if (lasr->status! = NGX_HTTP_OK) {r->headers_out.status = lasr->status;
R->header_only = 1;//???
rc = Ngx_http_send_header (r);
Ngx_http_finalize_request (R, RC);
return NGX_OK;
} r->headers_out.status = lasr->status;
R->headers_out.content_length_n = lasr->content->len; rc = Ngx_http_Send_header (R);
if (rc = = Ngx_error | | rc > NGX_OK | | r->header_only) {ngx_http_finalize_request (r, RC);
return NGX_OK;
} ngx_chain_t out;
ngx_buf_t b;
Ngx_memzero (&b, sizeof (ngx_buf_t));
B.temporary = 1; B.last_buf = 1;
//???
B.pos = lasr->content->data;
B.last = B.pos + lasr->content->len;
B.start = B.pos;
B.end = B.last;
Out.buf = &b;
Out.next = NULL;
rc = Ngx_http_output_filter (R, &out);
Ngx_http_finalize_request (R, RC);
return NGX_OK; } if (lasr->status = = Ngx_http_internal_server_error) {ngx_http_finalize_request (R, Ngx_http_internal_server_erro
R);
return NGX_OK;
} else if (lasr->status! = NGX_HTTP_OK) {r->headers_out.status = lasr->status;
R->header_only = 1;//???
rc = Ngx_http_send_header (r);
Ngx_http_finalize_request (R, RC);
return NGX_OK;
}//args = lasr->content; args = (ngx_str_t *) Ngx_palloc (R->pooL, sizeof (ngx_str_t));
if (args = = NULL) {ngx_http_finalize_request (R, Ngx_http_internal_server_error);
return NGX_OK;
} Args->len = R->args.len + 1 + lasr->content->len;
Args->data = (U_char *) Ngx_palloc (R->pool, Args->len);
if (Args->data = = NULL) {ngx_http_finalize_request (R, Ngx_http_internal_server_error);
return NGX_OK;
} ngx_memcpy (Args->data, R->args.data, R->args.len);
Args->data[r->args.len] = ' & ';
ngx_memcpy (args->data + r->args.len + 1, lasr->content->data, Lasr->content->len);
#if 0/*for Test *uri dont contain ' \ r ', ... */U_char *p = Lasr->content->data + lasr->content->len;
while (*--p = = ' \ n ') {args->len--;
} while (*--p = = ' \ n ') {ngx_http_finalize_request (R, Ngx_http_internal_server_error);
return NGX_OK;
} #endif goto Subrequest;
} else{args = &r->args; } CTX = (ngx_http_lauth_ext_ctx_t *) Ngx_pcalloc (r->Pool, sizeof (ngx_http_lauth_ext_ctx_t));
if (CTX = = NULL) {return ngx_error; } ctx->subrequests = Ngx_array_create (R->pool, Lauth_ext_cmd_args_num, sizeof (ngx_http_lauth_ext_subrequest))
;
if (ctx->subrequests = = NULL) {return ngx_error;
} ngx_http_set_ctx (R, CTX, Ngx_http_lauth_ext_module);
Subrequest:uri = (ngx_str_t *) Lacf->uris->elts + ctx->i;
Ctx->i + +;
LASR = (Ngx_http_lauth_ext_subrequest *) Ngx_array_push (ctx->subrequests);
Ngx_memzero (LASR, sizeof (ngx_http_lauth_ext_subrequest));
PS = (ngx_http_post_subrequest_t *) ngx_palloc (r->pool, sizeof (ngx_http_post_subrequest_t));
if (PS = = NULL) {return ngx_error;
} Ps->handler = Ngx_http_lauth_ext_done;
Ps->data = CTX; if (Ngx_http_subrequest (R, Uri, args, &LASR->SR, PS, ngx_http_subrequest_in_memory/* |
ngx_http_subrequest_waited*/)! = NGX_OK) {return ngx_error; } ngx_log_error (Ngx_log_debug, R->connection-> log, 0, "Lauth_ext request handler, Subrequest uri:%v args:%v", Uri, args);
return ngx_again; } static ngx_int_t Ngx_http_lauth_ext_done (ngx_http_request_t *r, void *data, ngx_int_t rc) {NGX_HTTP_LAUTH_EXT_CT
x_t *ctx = (ngx_http_lauth_ext_ctx_t *) data;
ngx_http_lauth_ext_subrequest* LASR = (ngx_http_lauth_ext_subrequest*) Ctx->subrequests->elts + (ctx->i-1);
Lasr->done = 1;
Lasr->status = r->headers_out.status; if (Lasr->status = = NGX_HTTP_OK) {if (R->upstream = = NULL) {ngx_log_error (Ngx_log_err, R->connection->log,
0, "Lauth_ext subrequest done, Subrequest does not support upstream, Uri:%v Args:%v",
&r->uri, &r->args);
Lasr->status = Ngx_http_internal_server_error;
Goto end;
} if (lasr->content = = NULL) {lasr->content = (ngx_str_t *) ngx_palloc (r->pool, sizeof (ngx_str_t)); if (lasr->content = = NULL) {lasr->status = Ngx_htTp_internal_server_error;
Goto end;
}} Lasr->content->len = r->headers_out.content_length_n;
Lasr->content->data = (U_char *) Ngx_palloc (R->pool, Lasr->content->len);
if (Lasr->content->data = = NULL) {lasr->status = Ngx_http_internal_server_error;
Goto end;
} ngx_memcpy (Lasr->content->data, R->upstream->buffer.pos, Lasr->content->len);
Goto end; } end:if (Lasr->content! = NULL) {ngx_log_error (ngx_log_debug, R->connection->log, 0, "Lau Th_ext subrequest Done, uri:%v args:%v rc:%i status:%i content:%v ", &r->uri, &r->args, R
C, Lasr->status, lasr->content); } else{Ngx_log_error (Ngx_log_debug, R->connection->log, 0, "Lauth_ext subrequest done, uri:%v
Args:%v rc:%i status:%i ", &r->uri, &r->args, RC, lasr->status); } R->parent->write_event_handler = (ngx_http_evenT_HANDLER_PT) Ngx_http_lauth_ext_handler;
return RC;
} static void * ngx_http_lauth_ext_create_conf (ngx_conf_t *cf) {ngx_http_lauth_ext_conf_t *conf;
conf = (ngx_http_lauth_ext_conf_t *) ngx_pcalloc (cf->pool, sizeof (ngx_http_lauth_ext_conf_t));
if (conf = = null) {return null;
} conf->n = Lauth_ext_cmd_args_num;
Conf->uris = Ngx_array_create (Cf->pool, Lauth_ext_cmd_args_num, sizeof (ngx_str_t));
if (Conf->uris = = NULL) {return ngx_conf_error;
} return conf; } Static char * Ngx_http_lauth_ext (ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {ngx_http_lauth_ext_conf_t *LACF
= (ngx_http_lauth_ext_conf_t *) conf;
ngx_http_core_loc_conf_t *CLCF;
ngx_str_t *uri, *value;
Value = (ngx_str_t *) cf->args->elts;
for (ngx_uint_t i = 1; I <= lacf->n; i++) {uri = (ngx_str_t *) Ngx_array_push (Lacf->uris);
*uri = Value[i]; Ngx_log_error (Ngx_log_debug, Cf->log, 0, "Lauth_ext args:%V", URI);
} CLCF = (ngx_http_core_loc_conf_t *) ngx_http_conf_get_module_loc_conf (cf, Ngx_http_core_module);
Clcf->handler = Ngx_http_lauth_ext_handler;
return NGX_CONF_OK;
}