]> git.r.bdr.sh - rbdr/ngx_http_office_hours_filter_module/blob - ngx_http_office_hours_filter_module.c
5175364f9d83490cf1e14ad020ec89ff79e2c318
[rbdr/ngx_http_office_hours_filter_module] / ngx_http_office_hours_filter_module.c
1 /*
2 * Copyright 2018 Rubén Beltrán del Río
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
5 * License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
10 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11 * specific language governing permissions and limitations under the License.
12 */
13
14
15 #include <ngx_config.h>
16 #include <ngx_core.h>
17 #include <ngx_http.h>
18
19 /*
20 * Declarations
21 */
22
23 /* Main Configuration Structure */
24
25 typedef struct {
26 ngx_array_t *office_hours;
27 } ngx_http_office_hours_conf_t;
28
29 /* Lifecycle Functions For Module Context */
30
31 static void *ngx_http_office_hours_create_conf(ngx_conf_t * cf);
32 static char *ngx_http_office_hours_merge_conf(ngx_conf_t * cf,
33 void *parent, void *child);
34 static ngx_int_t ngx_http_office_hours_init(ngx_conf_t * cf);
35
36 /* Configuration Handler */
37
38 static char *ngx_http_office_hours(ngx_conf_t * cf, ngx_command_t * cmd,
39 void *conf);
40
41 /* Body Filter Storage */
42
43 static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
44
45 /*
46 * Module Definitions
47 */
48
49 /* Module Directives */
50
51 static ngx_command_t ngx_http_office_hours_commands[] = {
52 {
53 ngx_string("office_hours"),
54 NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_1MORE,
55 ngx_http_office_hours,
56 NGX_HTTP_LOC_CONF_OFFSET,
57 offsetof(ngx_http_office_hours_conf_t, office_hours),
58 NULL
59 },
60
61 ngx_null_command
62 };
63
64
65 /* Module Context */
66
67 static ngx_http_module_t ngx_http_office_hours_filter_module_ctx = {
68 NULL, /* Preconfiguration */
69 ngx_http_office_hours_init, /* Postconfiguration */
70
71 NULL, /* Create main configuration */
72 NULL, /* Initialize main configuration */
73
74 NULL, /* Create server configuration */
75 NULL, /* Merge server configuration */
76
77 ngx_http_office_hours_create_conf, /* Create location configuration */
78 ngx_http_office_hours_merge_conf /* Merge location configuration */
79 };
80
81
82 /* Module Definition */
83
84 ngx_module_t ngx_http_office_hours_filter_module = {
85 NGX_MODULE_V1, //Module Version
86 &ngx_http_office_hours_filter_module_ctx, //Module context
87 ngx_http_office_hours_commands, //Module commands
88 NGX_HTTP_MODULE, //Module Type
89 NULL, //Initialize Master
90 NULL, //Initialize Module
91 NULL, //Initialize Process
92 NULL, //Initialize Thread
93 NULL, //Exit Thread
94 NULL, //Exit Process
95 NULL, //Exit Master
96 NGX_MODULE_V1_PADDING
97 };
98
99
100 /*
101 * Main Body Filter
102 * If the current time is within office hours, it goes to the next
103 * handler. Otherwise it returns 403 and the office hour listing.
104 */
105
106 static ngx_int_t
107 ngx_http_office_hours_body_filter(ngx_http_request_t * r, ngx_chain_t * in)
108 {
109
110 ngx_http_office_hours_conf_t *conf;
111 ngx_uint_t i;
112 ngx_str_t *hours;
113
114 conf =
115 ngx_http_get_module_loc_conf(r,
116 ngx_http_office_hours_filter_module);
117
118 if (conf->office_hours == NULL) {
119 ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0,
120 "Within office hours");
121 return ngx_http_next_body_filter(r, in);
122 }
123
124 ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0,
125 "Outside office hours");
126
127 hours = conf->office_hours->elts;
128
129 for (i = 0; i < conf->office_hours->nelts; ++i) {
130 ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0,
131 (const char *) hours[i].data);
132 }
133
134 r->keepalive = 0;
135 return NGX_HTTP_FORBIDDEN;
136 }
137
138 /*
139 * Callback for `office_hours ` directive
140 * Reads the configuration loaded from the config file(cf)
141 * And writes it to the right place in the module configuration(conf)
142 */
143
144 static char *ngx_http_office_hours(ngx_conf_t * cf, ngx_command_t * cmd,
145 void *conf)
146 {
147
148 char *conf_structure = conf;
149
150 ngx_array_t **office_hours;
151 ngx_str_t *hours;
152 ngx_str_t *value;
153 ngx_uint_t i;
154
155 /* Gets the array from the config structure using the defined
156 * offset, and if the pointer is unset it creates a new one.
157 * (The first element is the directive itself, so we should be
158 * offset by 1)
159 */
160 office_hours = (ngx_array_t **) (conf_structure + cmd->offset);
161
162 if (*office_hours == NGX_CONF_UNSET_PTR) {
163 *office_hours = ngx_array_create(cf->pool, cf->args->nelts - 1,
164 sizeof(ngx_str_t));
165
166 if (*office_hours == NULL) {
167 return NGX_CONF_ERROR;
168 }
169 }
170 value = cf->args->elts;
171
172 for (i = 1; i < cf->args->nelts; ++i) {
173 hours = ngx_array_push(*office_hours);
174 if (hours == NULL) {
175 return NGX_CONF_ERROR;
176 }
177 *hours = value[i];
178 }
179
180 return NGX_CONF_OK;
181 }
182
183
184 /*
185 * Config Creator
186 * Initializes the configuration structure
187 */
188
189 static void *ngx_http_office_hours_create_conf(ngx_conf_t * cf)
190 {
191
192 ngx_http_office_hours_conf_t *conf;
193
194 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_office_hours_conf_t));
195
196 if (conf == NULL) {
197 return NULL;
198 }
199 conf->office_hours = NGX_CONF_UNSET_PTR;
200
201 return conf;
202 }
203
204 /*
205 * Merge Config Values
206 * Sets the defaults for the configuration and merges
207 * with other configurations
208 */
209
210 static char *ngx_http_office_hours_merge_conf(ngx_conf_t * cf,
211 void *parent, void *child)
212 {
213
214 ngx_http_office_hours_conf_t *prev = parent;
215 ngx_http_office_hours_conf_t *conf = child;
216
217 ngx_conf_merge_ptr_value(conf->office_hours, prev->office_hours, NULL);
218
219 return NGX_CONF_OK;
220 }
221
222 /*
223 * Postconfig Initialization Handler
224 * Sets the request filter at the top of the chain
225 */
226
227 static ngx_int_t ngx_http_office_hours_init(ngx_conf_t * cf)
228 {
229
230 ngx_http_next_body_filter = ngx_http_top_body_filter;
231 ngx_http_top_body_filter = ngx_http_office_hours_body_filter;
232
233 return NGX_OK;
234 }