One Level Up
Top Level
src/http/ngx_http_priority.c - nginx-1.31.9
nginx/ @ 2a3a19c6f
Functions defined
Macros defined
Source code
- #include <ngx_config.h>
- #include <ngx_core.h>
- #include <ngx_http.h>
- #define NGX_HTTP_PRIORITY_DEFAULT_URGENCY 3
- #define NGX_HTTP_PRIORITY_URGENCY_MIN 0
- #define NGX_HTTP_PRIORITY_URGENCY_MAX 7
- #define NGX_HTTP_PRIORITY_INTEGER 0
- #define NGX_HTTP_PRIORITY_BOOLEAN 1
- #define NGX_HTTP_PRIORITY_OTHER 2
- #define NGX_HTTP_PRIORITY_MAX_MEMBERS 1024
- #define NGX_HTTP_PRIORITY_MAX_INNER_ITEMS 256
- #define NGX_HTTP_PRIORITY_MAX_PARAMS 256
- #define NGX_HTTP_PRIORITY_MAX_STRING 1024
- #define NGX_HTTP_PRIORITY_MAX_TOKEN 512
- #define NGX_HTTP_PRIORITY_MAX_BINARY 21848
- static ngx_int_t ngx_http_priority_parse_key(u_char **pos, u_char *end,
- ngx_str_t *key);
- static ngx_int_t ngx_http_priority_parse_member(u_char **pos, u_char *end,
- ngx_str_t *key, ngx_int_t *type, ngx_int_t *value);
- static ngx_int_t ngx_http_priority_parse_value(u_char **pos, u_char *end,
- ngx_int_t *type, ngx_int_t *value);
- static ngx_int_t ngx_http_priority_parse_inner_list(u_char **pos, u_char *end);
- static ngx_int_t ngx_http_priority_parse_bare_item(u_char **pos, u_char *end,
- ngx_int_t *type, ngx_int_t *value);
- static ngx_int_t ngx_http_priority_parse_params(u_char **pos, u_char *end);
- static ngx_int_t ngx_http_priority_parse_number(u_char **pos, u_char *end,
- ngx_int_t *type, ngx_int_t *value);
- static ngx_int_t ngx_http_priority_parse_string(u_char **pos, u_char *end);
- static ngx_int_t ngx_http_priority_parse_token(u_char **pos, u_char *end);
- static ngx_int_t ngx_http_priority_parse_binary(u_char **pos, u_char *end);
- void
- ngx_http_priority_state_init(ngx_http_priority_state_t *ps)
- {
- ngx_memzero(ps, sizeof(ngx_http_priority_state_t));
- ps->client.urgency = NGX_HTTP_PRIORITY_DEFAULT_URGENCY;
- ps->server.urgency = NGX_HTTP_PRIORITY_DEFAULT_URGENCY;
- ps->effective.urgency = NGX_HTTP_PRIORITY_DEFAULT_URGENCY;
- }
- ngx_int_t
- ngx_http_priority_parse(ngx_str_t *field, ngx_http_priority_t *p)
- {
- u_char *last, *end;
- ngx_str_t key;
- ngx_int_t type, value;
- ngx_uint_t members;
- p->urgency = NGX_HTTP_PRIORITY_DEFAULT_URGENCY;
- p->incremental = 0;
- p->urgency_set = 0;
- p->incremental_set = 0;
- if (field == NULL) {
- return NGX_OK;
- }
-
- last = field->data;
- end = last + field->len;
- members = 0;
-
- while (last < end && *last == ' ') {
- last++;
- }
- while (last < end) {
- if (++members > NGX_HTTP_PRIORITY_MAX_MEMBERS) {
- return NGX_ERROR;
- }
- if (ngx_http_priority_parse_member(&last, end, &key, &type, &value)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (key.len == 1 && key.data[0] == 'u') {
- p->urgency = NGX_HTTP_PRIORITY_DEFAULT_URGENCY;
- p->urgency_set = 0;
- if (type == NGX_HTTP_PRIORITY_INTEGER
- && value >= NGX_HTTP_PRIORITY_URGENCY_MIN
- && value <= NGX_HTTP_PRIORITY_URGENCY_MAX)
- {
- p->urgency = (unsigned) value;
- p->urgency_set = 1;
- }
- } else if (key.len == 1 && key.data[0] == 'i') {
- p->incremental = 0;
- p->incremental_set = 0;
- if (type == NGX_HTTP_PRIORITY_BOOLEAN) {
- p->incremental = (unsigned) value;
- p->incremental_set = 1;
- }
- }
- while (last < end && (*last == ' ' || *last == '\t')) {
- last++;
- }
- if (last == end) {
- break;
- }
- if (*last++ != ',') {
- return NGX_ERROR;
- }
- while (last < end && (*last == ' ' || *last == '\t')) {
- last++;
- }
-
- if (last == end) {
- return NGX_ERROR;
- }
- }
- return NGX_OK;
- }
- static ngx_int_t
- ngx_http_priority_parse_member(u_char **pos, u_char *end, ngx_str_t *key,
- ngx_int_t *type, ngx_int_t *value)
- {
- u_char *last;
- last = *pos;
- if (ngx_http_priority_parse_key(&last, end, key) != NGX_OK) {
- return NGX_ERROR;
- }
- if (last < end && *last == '=') {
- last++;
- if (ngx_http_priority_parse_value(&last, end, type, value) != NGX_OK) {
- return NGX_ERROR;
- }
- } else {
- *type = NGX_HTTP_PRIORITY_BOOLEAN;
- *value = 1;
- if (ngx_http_priority_parse_params(&last, end) != NGX_OK) {
- return NGX_ERROR;
- }
- }
- *pos = last;
- return NGX_OK;
- }
- static ngx_int_t
- ngx_http_priority_parse_value(u_char **pos, u_char *end, ngx_int_t *type,
- ngx_int_t *value)
- {
- u_char *last;
- last = *pos;
- if (last < end && *last == '(') {
- *type = NGX_HTTP_PRIORITY_OTHER;
- *value = 0;
- if (ngx_http_priority_parse_inner_list(&last, end) != NGX_OK) {
- return NGX_ERROR;
- }
- } else {
- if (ngx_http_priority_parse_bare_item(&last, end, type, value)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
- if (ngx_http_priority_parse_params(&last, end) != NGX_OK) {
- return NGX_ERROR;
- }
- *pos = last;
- return NGX_OK;
- }
- static ngx_int_t
- ngx_http_priority_parse_key(u_char **pos, u_char *end, ngx_str_t *key)
- {
- u_char *last, ch;
- last = *pos;
- if (last == end) {
- return NGX_ERROR;
- }
- ch = *last;
- if (!((ch >= 'a' && ch <= 'z') || ch == '*')) {
- return NGX_ERROR;
- }
- key->data = last;
- do {
- last++;
- if (last == end) {
- break;
- }
- ch = *last;
- } while ((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')
- || ch == '_' || ch == '-' || ch == '.' || ch == '*');
- key->len = last - *pos;
- *pos = last;
- return NGX_OK;
- }
- static ngx_int_t
- ngx_http_priority_parse_params(u_char **pos, u_char *end)
- {
- u_char *last;
- ngx_str_t key;
- ngx_int_t type, value;
- ngx_uint_t params;
- last = *pos;
- params = 0;
- while (last < end && *last == ';') {
- last++;
- if (++params > NGX_HTTP_PRIORITY_MAX_PARAMS) {
- return NGX_ERROR;
- }
-
- while (last < end && *last == ' ') {
- last++;
- }
- if (ngx_http_priority_parse_key(&last, end, &key) != NGX_OK) {
- return NGX_ERROR;
- }
- if (last < end && *last == '=') {
- last++;
- if (ngx_http_priority_parse_bare_item(&last, end, &type, &value)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
- }
- *pos = last;
- return NGX_OK;
- }
- static ngx_int_t
- ngx_http_priority_parse_inner_list(u_char **pos, u_char *end)
- {
- u_char *last;
- ngx_int_t type, value;
- ngx_uint_t items;
- last = *pos + 1;
- items = 0;
- for ( ;; ) {
- while (last < end && *last == ' ') {
- last++;
- }
- if (last < end && *last == ')') {
- *pos = last + 1;
- return NGX_OK;
- }
- if (++items > NGX_HTTP_PRIORITY_MAX_INNER_ITEMS) {
- return NGX_ERROR;
- }
- if (ngx_http_priority_parse_bare_item(&last, end, &type, &value)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- if (ngx_http_priority_parse_params(&last, end) != NGX_OK) {
- return NGX_ERROR;
- }
- if (last == end) {
- return NGX_ERROR;
- }
- if (*last != ' ' && *last != ')') {
- return NGX_ERROR;
- }
- }
- }
- static ngx_int_t
- ngx_http_priority_parse_bare_item(u_char **pos, u_char *end, ngx_int_t *type,
- ngx_int_t *value)
- {
- u_char ch;
- if (*pos == end) {
- return NGX_ERROR;
- }
- ch = **pos;
- if (ch == '-' || (ch >= '0' && ch <= '9')) {
- return ngx_http_priority_parse_number(pos, end, type, value);
- }
- if (ch == '?') {
- (*pos)++;
- if (*pos == end || (**pos != '0' && **pos != '1')) {
- return NGX_ERROR;
- }
- *type = NGX_HTTP_PRIORITY_BOOLEAN;
- *value = (**pos == '1');
- (*pos)++;
- return NGX_OK;
- }
- *type = NGX_HTTP_PRIORITY_OTHER;
- if (ch == '"') {
- return ngx_http_priority_parse_string(pos, end);
- }
- if (ch == ':') {
- return ngx_http_priority_parse_binary(pos, end);
- }
- if (((ch | 0x20) >= 'a' && (ch | 0x20) <= 'z') || ch == '*') {
- return ngx_http_priority_parse_token(pos, end);
- }
- return NGX_ERROR;
- }
- static ngx_int_t
- ngx_http_priority_parse_number(u_char **pos, u_char *end, ngx_int_t *type,
- ngx_int_t *value)
- {
- u_char *last, *start;
- ngx_int_t n;
- ngx_uint_t neg, decimal, digits, frac;
- last = *pos;
- neg = 0;
- if (*last == '-') {
- neg = 1;
- last++;
- }
- start = last;
- decimal = 0;
- digits = 0;
- frac = 0;
-
- while (last < end) {
- if (*last >= '0' && *last <= '9') {
- digits++;
-
- if (!decimal && digits > 15) {
- return NGX_ERROR;
- }
-
- if (decimal && ++frac > 3) {
- return NGX_ERROR;
- }
- last++;
- continue;
- }
-
- if (*last == '.' && !decimal) {
-
- if (digits == 0 || digits > 12) {
- return NGX_ERROR;
- }
- decimal = 1;
- last++;
- continue;
- }
- break;
- }
- if (digits == 0) {
- return NGX_ERROR;
- }
- if (decimal) {
-
- if (frac == 0) {
- return NGX_ERROR;
- }
-
- *type = NGX_HTTP_PRIORITY_OTHER;
- *value = 0;
- *pos = last;
- return NGX_OK;
- }
- n = ngx_atoi(start, last - start);
- if (n == NGX_ERROR) {
-
- *type = NGX_HTTP_PRIORITY_OTHER;
- *value = 0;
- *pos = last;
- return NGX_OK;
- }
- *type = NGX_HTTP_PRIORITY_INTEGER;
- *value = neg ? -n : n;
- *pos = last;
- return NGX_OK;
- }
- static ngx_int_t
- ngx_http_priority_parse_string(u_char **pos, u_char *end)
- {
- u_char *last, ch;
- ngx_uint_t len;
- last = *pos + 1;
- len = 0;
- while (last < end) {
- ch = *last++;
- if (ch == '\\') {
- if (last == end || (*last != '"' && *last != '\\')) {
- return NGX_ERROR;
- }
- last++;
- if (++len > NGX_HTTP_PRIORITY_MAX_STRING) {
- return NGX_ERROR;
- }
- continue;
- }
- if (ch == '"') {
- *pos = last;
- return NGX_OK;
- }
- if (ch < 0x20 || ch >= 0x7f) {
- return NGX_ERROR;
- }
- if (++len > NGX_HTTP_PRIORITY_MAX_STRING) {
- return NGX_ERROR;
- }
- }
- return NGX_ERROR;
- }
- static ngx_int_t
- ngx_http_priority_parse_token(u_char **pos, u_char *end)
- {
- u_char *last, ch;
- last = *pos + 1;
- while (last < end) {
- ch = *last;
- if (ch == ':' || ch == '/'
- || ((ch | 0x20) >= 'a' && (ch | 0x20) <= 'z')
- || (ch >= '0' && ch <= '9')
- || ch == '!' || ch == '#' || ch == '$' || ch == '%'
- || ch == '&' || ch == '\'' || ch == '*' || ch == '+'
- || ch == '-' || ch == '.' || ch == '^' || ch == '_'
- || ch == '`' || ch == '|' || ch == '~')
- {
- if ((ngx_uint_t) (last - *pos) >= NGX_HTTP_PRIORITY_MAX_TOKEN) {
- return NGX_ERROR;
- }
- last++;
- continue;
- }
- break;
- }
- *pos = last;
- return NGX_OK;
- }
- static ngx_int_t
- ngx_http_priority_parse_binary(u_char **pos, u_char *end)
- {
- u_char *last, ch;
- ngx_uint_t len;
- last = *pos + 1;
- len = 0;
- while (last < end) {
- ch = *last++;
- if (ch == ':') {
-
- if (len % 4 == 1) {
- return NGX_ERROR;
- }
- *pos = last;
- return NGX_OK;
- }
- if (!(((ch | 0x20) >= 'a' && (ch | 0x20) <= 'z')
- || (ch >= '0' && ch <= '9')
- || ch == '+' || ch == '/' || ch == '='))
- {
- return NGX_ERROR;
- }
- if (++len > NGX_HTTP_PRIORITY_MAX_BINARY) {
- return NGX_ERROR;
- }
- }
- return NGX_ERROR;
- }
- void
- ngx_http_priority_state_update(ngx_http_priority_state_t *ps)
- {
- ngx_http_priority_t *e;
- e = &ps->effective;
- *e = ps->client;
- if (ps->server.urgency_set) {
- e->urgency = ps->server.urgency;
- e->urgency_set = 1;
- }
- if (ps->server.incremental_set) {
- e->incremental = ps->server.incremental;
- e->incremental_set = 1;
- }
- }
One Level Up
Top Level