diff --git a/README b/README index d26c879..39bd61d 100644 --- a/README +++ b/README @@ -16,7 +16,8 @@ Currently only inspects the following headers: Range, If-Range, If-Unmodified-Since, If-Modified-Since, Date, Accept-Encoding, Accept-Language, Accept-Charset, Max-Forwards, If-Match, - If-None-Match, Last-Modified, Content-Length, Expires + If-None-Match, Last-Modified, Content-Length, Expires, + Content-Language Report Bugs Create a ticket on the issue tracking interface of GitHub: diff --git a/ngx_http_header_inspect.c b/ngx_http_header_inspect.c index 18b188a..d01bd5a 100644 --- a/ngx_http_header_inspect.c +++ b/ngx_http_header_inspect.c @@ -29,6 +29,7 @@ static ngx_int_t ngx_header_inspect_range_header(ngx_header_inspect_loc_conf_t *conf, ngx_log_t *log, ngx_str_t value); static ngx_int_t ngx_header_inspect_acceptencoding_header(ngx_header_inspect_loc_conf_t *conf, ngx_log_t *log, ngx_str_t value); static ngx_int_t ngx_header_inspect_acceptlanguage_header(ngx_header_inspect_loc_conf_t *conf, ngx_log_t *log, ngx_str_t value); +static ngx_int_t ngx_header_inspect_contentlanguage_header(ngx_header_inspect_loc_conf_t *conf, ngx_log_t *log, ngx_str_t value); static ngx_int_t ngx_header_inspect_acceptcharset_header(ngx_header_inspect_loc_conf_t *conf, ngx_log_t *log, ngx_str_t value); static ngx_int_t ngx_header_inspect_digit_header(char* header, ngx_header_inspect_loc_conf_t *conf, ngx_log_t *log, ngx_str_t value); static ngx_int_t ngx_header_inspect_ifmatch_header(char* header, ngx_header_inspect_loc_conf_t *conf, ngx_log_t *log, ngx_str_t value); @@ -1006,6 +1007,56 @@ return rc; } +static ngx_int_t ngx_header_inspect_contentlanguage_header(ngx_header_inspect_loc_conf_t *conf, ngx_log_t *log, ngx_str_t value) { + ngx_int_t rc = NGX_AGAIN; + ngx_uint_t i = 0; + ngx_uint_t v; + + if ((value.len == 0) || ((value.len == 1) && (value.data[0] == '*'))) { + ngx_log_error(NGX_LOG_ALERT, log, 0, "header_inspect: Content-Language header \"%s\" too short", value.data); + return NGX_ERROR; + } + + while ( i < value.len ) { + if (value.data[i] == '*') { + /* hack, to prevent parse_languagerange from matching '*' */ + ngx_log_error(NGX_LOG_ALERT, log, 0, "header_inspect: illegal char at position %d in Content-Language header \"%s\"", i, value.data); + rc = NGX_ERROR; + break; + } + if (ngx_header_inspect_parse_languagerange(&(value.data[i]), value.len-i, &v) != NGX_OK) { + ngx_log_error(NGX_LOG_ALERT, log, 0, "header_inspect: invalid language-range at position %d in Content-Language header \"%s\"", i, value.data); + rc = NGX_ERROR; + break; + } + i += v; + if ((value.data[i] == ' ') && (i < value.len)) { + i++; + } + if (i == value.len) { + rc = NGX_OK; + break; + } + if (value.data[i] != ',') { + ngx_log_error(NGX_LOG_ALERT, log, 0, "header_inspect: illegal char at position %d in Content-Language header \"%s\"", i, value.data); + rc = NGX_ERROR; + break; + } + i++; + if ((value.data[i] == ' ') && (i < value.len)) { + i++; + } + } + + if (rc == NGX_AGAIN) { + ngx_log_error(NGX_LOG_ALERT, log, 0, "header_inspect: unexpected end of Content-Language header \"%s\"", value.data); + rc = NGX_ERROR; + } + + return rc; + +} + static ngx_int_t ngx_header_inspect_acceptlanguage_header(ngx_header_inspect_loc_conf_t *conf, ngx_log_t *log, ngx_str_t value) { ngx_int_t rc = NGX_AGAIN; ngx_uint_t i = 0; @@ -1224,6 +1275,11 @@ if ((rc != NGX_OK) && conf->block) { return NGX_HTTP_BAD_REQUEST; } + } else if ((h[i].key.len == 16) && (ngx_strcmp("Content-Language", h[i].key.data) == 0) ) { + rc = ngx_header_inspect_contentlanguage_header(conf, r->connection->log, h[i].value); + if ((rc != NGX_OK) && conf->block) { + return NGX_HTTP_BAD_REQUEST; + } } else if ((h[i].key.len == 15) && (ngx_strcmp("Accept-Language", h[i].key.data) == 0) ) { rc = ngx_header_inspect_acceptlanguage_header(conf, r->connection->log, h[i].value); if ((rc != NGX_OK) && conf->block) {