X-Git-Url: https://git.r.bdr.sh/rbdr/ngx_http_office_hours_filter_module/blobdiff_plain/bbe15175600a074663d368a9f44e27848e3ed915..67206816625c33f24d0135c4df780c24afe6fece:/ngx_http_office_hours_filter_module.c diff --git a/ngx_http_office_hours_filter_module.c b/ngx_http_office_hours_filter_module.c index ee914b1..b9df683 100644 --- a/ngx_http_office_hours_filter_module.c +++ b/ngx_http_office_hours_filter_module.c @@ -25,6 +25,7 @@ const ngx_uint_t WEEK_LENGTH = 7; const char * CLOSED_TOKEN = "closed"; const ngx_str_t TIME_REGEX = ngx_string("([0-9]{1,2})(?:\\:([0-9]{2}))?\\-([0-9]{1,2})(?:\\:([0-9]{2}))?"); +const ngx_str_t OUTPUT_HTML = ngx_string("This website is currently closed!

This website is currently closed!

This website has closed for the day, please check our office hours below

"); /* Main Configuration Structure */ @@ -44,8 +45,9 @@ 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); -/* Body Filter Storage */ +/* Filter Storage */ +static ngx_http_output_header_filter_pt ngx_http_next_header_filter; static ngx_http_output_body_filter_pt ngx_http_next_body_filter; /* Utility Functions */ @@ -114,17 +116,60 @@ ngx_module_t ngx_http_office_hours_filter_module = { }; +/* + * Main Header Filter + * If the current time is within office hours, it goes to the next + * handler. Otherwise it sets the headers to 403 + */ + +static ngx_int_t +ngx_http_office_hours_header_filter(ngx_http_request_t * r) +{ + + ngx_uint_t ** parsed_office_hours; + ngx_http_office_hours_conf_t *conf; + + 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, + "Office hours disabled"); + return ngx_http_next_header_filter(r); + } + + parsed_office_hours = parse_office_hours(conf->office_hours); + + if (within_office_hours(parsed_office_hours)) { + ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, + "Within office hours"); + return ngx_http_next_header_filter(r); + } + + ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, + "Outside office hours"); + + r->headers_out.status = NGX_HTTP_FORBIDDEN; + r->headers_out.content_length_n = OUTPUT_HTML.len; + + return ngx_http_next_header_filter(r); +} + /* * Main Body Filter * If the current time is within office hours, it goes to the next - * handler. Otherwise it returns 403 and the office hour listing. + * handler. Otherwise it replaces the body with the office hours. */ static ngx_int_t -ngx_http_office_hours_body_filter(ngx_http_request_t * r, ngx_chain_t * in) +ngx_http_office_hours_body_filter(ngx_http_request_t * r, ngx_chain_t *in) { + ngx_buf_t *b; ngx_uint_t ** parsed_office_hours; + ngx_chain_t out; ngx_http_office_hours_conf_t *conf; conf = @@ -149,8 +194,24 @@ ngx_http_office_hours_body_filter(ngx_http_request_t * r, ngx_chain_t * in) ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "Outside office hours"); - r->keepalive = 0; - return NGX_HTTP_FORBIDDEN; + b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); + if (b == NULL) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate response buffer."); + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + out.buf = b; + out.next = NULL; + + b->start = OUTPUT_HTML.data; + b->pos = b->start; + b->end = OUTPUT_HTML.data + OUTPUT_HTML.len; + b->last = b->end; + + b->memory = 1; + b->last_buf = 1; + + return ngx_http_next_body_filter(r, &out); } /* @@ -374,6 +435,9 @@ static ngx_uint_t parse_number(ngx_str_t string, ngx_uint_t start, ngx_uint_t en static ngx_int_t ngx_http_office_hours_init(ngx_conf_t * cf) { + ngx_http_next_header_filter = ngx_http_top_header_filter; + ngx_http_top_header_filter = ngx_http_office_hours_header_filter; + ngx_http_next_body_filter = ngx_http_top_body_filter; ngx_http_top_body_filter = ngx_http_office_hours_body_filter;