Skip to content

Commit 097d0b7

Browse files
author
Chrono Law
committed
filter module
1 parent ddda6ea commit 097d0b7

File tree

5 files changed

+260
-0
lines changed

5 files changed

+260
-0
lines changed

modules/filter/ModNdgFooter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (c) 2015
2+
// Author: Chrono Law
3+
4+
#include "NdgFooterInit.hpp"
5+
6+
auto ndg_footer_module = NdgFooterInit::module();
7+

modules/filter/NdgFooterConf.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) 2015
2+
// Author: Chrono Law
3+
#ifndef _NDG_FOOTER_CONF_HPP
4+
#define _NDG_FOOTER_CONF_HPP
5+
6+
#include "NgxAll.hpp"
7+
8+
class NdgFooterConf final
9+
{
10+
public:
11+
typedef NdgFooterConf this_type;
12+
public:
13+
NdgFooterConf() = default;
14+
~NdgFooterConf() = default;
15+
public:
16+
ngx_array_t* headers;
17+
ngx_str_t footer;
18+
public:
19+
static void* create(ngx_conf_t* cf)
20+
{
21+
return NgxPool(cf).alloc<this_type>();
22+
}
23+
24+
};
25+
26+
struct NdgFooterCtx final
27+
{
28+
int flag = 0;
29+
};
30+
31+
NGX_MOD_INSTANCE(NdgFooterModule, ndg_footer_module, NdgFooterConf)
32+
33+
#endif //_NDG_FOOTER_CONF_HPP

modules/filter/NdgFooterHandler.hpp

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// Copyright (c) 2015
2+
// Author: Chrono Law
3+
#ifndef _NDG_FOOTER_HANDLER_HPP
4+
#define _NDG_FOOTER_HANDLER_HPP
5+
6+
#include "NdgFooterConf.hpp"
7+
8+
class NdgFooterHandler final
9+
{
10+
public:
11+
typedef NdgFooterHandler this_type;
12+
typedef NdgFooterModule this_module;
13+
typedef NgxFilter<this_type> this_filter;
14+
public:
15+
static ngx_int_t init(ngx_conf_t* cf)
16+
{
17+
this_filter::init(&this_type::header_filter, &this_type::body_filter);
18+
return NGX_OK;
19+
}
20+
public:
21+
static ngx_int_t header_filter(ngx_http_request_t *r)
22+
try
23+
{
24+
do_header_filter(r);
25+
return this_filter::next(r);
26+
}
27+
catch(const NgxException& e)
28+
{
29+
return e.code();
30+
}
31+
32+
static void do_header_filter(ngx_http_request_t *r)
33+
{
34+
auto& ctx = this_module::instance().data<NdgFooterCtx>(r);
35+
if(ctx.flag)
36+
{
37+
return;
38+
}
39+
40+
ctx.flag = 1;
41+
NgxResponse resp(r);
42+
43+
auto& cf = this_module::instance().conf().loc(r);
44+
45+
NgxKvArray headers = cf.headers;
46+
47+
for(auto i = 0u; i < headers.size();++i)
48+
{
49+
auto& header = headers[i];
50+
51+
ngx_table_elt_t kv;
52+
53+
kv.hash = 1;
54+
kv.key = header.key;
55+
kv.value = header.value;
56+
57+
resp.headers().add(kv);
58+
}
59+
60+
// check r->header_only r->method & NGX_HTTP_HEAD
61+
NgxString footer = cf.footer;
62+
if(footer.empty())
63+
{
64+
return;
65+
}
66+
67+
auto len = resp.headers()->content_length_n;
68+
if(len > 0)
69+
{
70+
resp.length(len + footer.size());
71+
}
72+
}
73+
74+
public:
75+
static ngx_int_t body_filter(ngx_http_request_t *r, ngx_chain_t *in)
76+
try
77+
{
78+
do_body_filter(r, in);
79+
return this_filter::next(r, in);
80+
}
81+
catch(const NgxException& e)
82+
{
83+
return e.code();
84+
}
85+
86+
static void do_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
87+
{
88+
auto& cf = this_module::instance().conf().loc(r);
89+
90+
NgxString footer = cf.footer;
91+
if(footer.empty())
92+
{
93+
return;
94+
}
95+
96+
auto& ctx = this_module::instance().data<NdgFooterCtx>(r);
97+
if(ctx.flag != 1)
98+
{
99+
return;
100+
}
101+
102+
NgxChain ch = in;
103+
auto p = ch.begin();
104+
for(; p != ch.end();++p)
105+
{
106+
if(p->data().last())
107+
{
108+
break;
109+
}
110+
}
111+
112+
if(p == ch.end())
113+
{
114+
return;
115+
}
116+
117+
ctx.flag = 2;
118+
119+
NgxPool pool(r);
120+
121+
NgxBuf buf = pool.buffer();
122+
buf.range(footer);
123+
buf.finish();
124+
125+
if(!p->data().size())
126+
{
127+
p->set(buf);
128+
return;
129+
}
130+
131+
NgxChainNode n = pool.chain();
132+
n.set(buf);
133+
n.finish();
134+
135+
p->link(n);
136+
p->data().finish(false);
137+
}
138+
};
139+
140+
#endif //_NDG_FOOTER_HANDLER_HPP

modules/filter/NdgFooterInit.hpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright (c) 2015
2+
// Author: Chrono Law
3+
#ifndef _NDG_FOOTER_INIT_HPP
4+
#define _NDG_FOOTER_INIT_HPP
5+
6+
#include "NdgFooterConf.hpp"
7+
#include "NdgFooterHandler.hpp"
8+
9+
class NdgFooterInit final
10+
{
11+
public:
12+
typedef NdgFooterConf conf_type;
13+
typedef NdgFooterHandler handler_type;
14+
typedef NdgFooterInit this_type;
15+
public:
16+
static ngx_command_t* cmds()
17+
{
18+
static ngx_command_t n[] =
19+
{
20+
NgxCommand(
21+
ngx_string("ndg_header"),
22+
NgxTake(NGX_HTTP_LOC_CONF, 2),
23+
ngx_conf_set_keyval_slot,
24+
NGX_HTTP_LOC_CONF_OFFSET,
25+
offsetof(conf_type, headers)
26+
),
27+
28+
NgxCommand(
29+
ngx_string("ndg_footer"),
30+
NgxTake(NGX_HTTP_LOC_CONF, 1),
31+
ngx_conf_set_str_slot,
32+
NGX_HTTP_LOC_CONF_OFFSET,
33+
offsetof(conf_type, footer)
34+
),
35+
36+
NgxCommand()
37+
};
38+
39+
return n;
40+
}
41+
public:
42+
static ngx_http_module_t* ctx()
43+
{
44+
static ngx_http_module_t c =
45+
{
46+
NGX_MODULE_NULL(1),
47+
&handler_type::init,
48+
NGX_MODULE_NULL(4),
49+
&conf_type::create,
50+
NGX_MODULE_NULL(1),
51+
};
52+
53+
return &c;
54+
}
55+
public:
56+
static const ngx_module_t& module()
57+
{
58+
static ngx_module_t m =
59+
{
60+
NGX_MODULE_V1,
61+
62+
ctx(),
63+
cmds(),
64+
65+
NGX_HTTP_MODULE,
66+
NGX_MODULE_NULL(7),
67+
NGX_MODULE_V1_PADDING
68+
};
69+
70+
return m;
71+
}
72+
};
73+
74+
#endif //_NDG_FOOTER_INIT_HPP

modules/filter/config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#./configure --add-module=$HOME/ngx_cpp_dev/modules/footer
2+
3+
ngx_addon_name=ndg_footer_module
4+
5+
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES ndg_footer_module"
6+
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ModNdgFooter.cpp"

0 commit comments

Comments
 (0)