--- /dev/null
+/*
+ * Copyright 2018 Rubén Beltrán del Río
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+// Module Config Definitions
+
+typedef struct {
+ ngx_array_t *office_hours;
+} ngx_http_office_hours_conf_t;
+
+static void *ngx_http_office_hours_create_conf(ngx_conf_t * cf);
+static char *ngx_http_office_hours_merge_conf(ngx_conf_t * cf, void *parent, void *child);
+static ngx_int_t ngx_http_office_hours_init(ngx_conf_t * cf);
+
+static char *ngx_http_office_hours(ngx_conf_t * cf, ngx_command_t * cmd, void *conf);
+
+//Module Directive Definitions
+
+static ngx_command_t ngx_http_office_hours_commands[] = {
+ {
+ ngx_string("office_hours"),
+ NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_1MORE,
+ ngx_http_office_hours,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_office_hours_conf_t, office_hours),
+ NULL
+ },
+
+ ngx_null_command
+};
+
+//Define the module context
+
+static ngx_http_module_t ngx_http_office_hours_filter_module_ctx = {
+ NULL, //Preconfiguration
+ ngx_http_office_hours_init, //Postconfiguration
+
+ NULL, //Create main configuration
+ NULL, //Initialize main configuration
+ NULL, //Create server configuration
+ NULL, //Merge server configuration
+
+ ngx_http_office_hours_create_conf, //Create location configuration
+ ngx_http_office_hours_merge_conf // Merge location configuration
+};
+
+//Define the module
+
+ngx_module_t ngx_http_office_hours_filter_module = {
+ NGX_MODULE_V1, //Module Version
+ & ngx_http_office_hours_filter_module_ctx, //Module context
+ ngx_http_office_hours_commands, //Module commands
+ NGX_HTTP_MODULE, //Module Type
+ NULL, //Initialize Master
+ NULL, //Initialize Module
+ NULL, //Initialize Process
+ NULL, //Initialize Thread
+ NULL, //Exit Thread
+ NULL, //Exit Process
+ NULL, //Exit Master
+ NGX_MODULE_V1_PADDING
+};
+
+
+//Main Body Filter
+
+static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
+
+static ngx_int_t
+ngx_http_office_hours_body_filter(ngx_http_request_t * r, ngx_chain_t * in) {
+
+ngx_http_office_hours_conf_t *conf;
+ngx_uint_t i;
+ngx_str_t *hours;
+
+ conf = ngx_http_get_module_loc_conf(r, ngx_http_office_hours_filter_module);
+
+ if (conf->office_hours == NULL) {
+
+ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "Within office hours");
+
+ return ngx_http_next_body_filter(r, in);
+ }
+
+ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "Outside office hours");
+
+ hours = conf->office_hours->elts;
+
+ for (i = 0; i < conf->office_hours->nelts; ++i) {
+ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, (const char *)hours[i].data);
+ }
+
+ r->keepalive = 0;
+ return NGX_HTTP_FORBIDDEN;
+}
+
+//Read Arguments from config file
+
+static char *
+ngx_http_office_hours(ngx_conf_t * cf, ngx_command_t * cmd, void *conf) {
+
+char *conf_structure = conf;
+
+ngx_array_t **office_hours;
+ngx_str_t *hours;
+ngx_str_t *value;
+ngx_uint_t i;
+
+ //Gets the array from the config structure using the defined
+ // offset, and if the
+ pointer is unset it creates a new one.
+ //
+ //(The first element is the directive itself, so we should be
+ // offset by 1)
+ office_hours = (ngx_array_t **) (conf_structure + cmd->offset);
+
+ if (*office_hours == NGX_CONF_UNSET_PTR) {
+ *office_hours = ngx_array_create(cf->pool, cf->args->nelts - 1,
+ sizeof(ngx_str_t));
+
+ if (*office_hours == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ value = cf->args->elts;
+
+ for (i = 1; i < cf->args->nelts; ++i) {
+
+ hours = ngx_array_push(*office_hours);
+ if (hours == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *hours = value[i];
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+//Initialize the Configuration Object
+
+static void *
+ngx_http_office_hours_create_conf(ngx_conf_t * cf) {
+
+ngx_http_office_hours_conf_t *conf;
+
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_office_hours_conf_t));
+
+ if (conf == NULL) {
+ return NULL;
+ }
+
+ conf->office_hours = NGX_CONF_UNSET_PTR;
+
+ return conf;
+}
+
+//Merge Config Values
+
+static char *
+ngx_http_office_hours_merge_conf(ngx_conf_t * cf, void *parent, void *child) {
+
+ngx_http_office_hours_conf_t *prev = parent;
+ngx_http_office_hours_conf_t *conf = child;
+
+ ngx_conf_merge_ptr_value(conf->office_hours, prev->office_hours, NULL);
+
+ return NGX_CONF_OK;
+}
+
+//Postconfig Initialization Handler
+// Sets the request filter at the top of the chain
+
+static ngx_int_t
+ngx_http_office_hours_init(ngx_conf_t * cf) {
+
+ ngx_http_next_body_filter = ngx_http_top_body_filter;
+ ngx_http_top_body_filter = ngx_http_office_hours_body_filter;
+
+ return NGX_OK;
+}