nxt_http_route.c (1061:2a57bdac6c0e) nxt_http_route.c (1062:8e8258a5a880)
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_router.h>
8#include <nxt_http.h>

--- 26 unchanged lines hidden (view full) ---

35
36
37typedef struct {
38 nxt_conf_value_t *host;
39 nxt_conf_value_t *uri;
40 nxt_conf_value_t *method;
41 nxt_conf_value_t *headers;
42 nxt_conf_value_t *arguments;
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_router.h>
8#include <nxt_http.h>

--- 26 unchanged lines hidden (view full) ---

35
36
37typedef struct {
38 nxt_conf_value_t *host;
39 nxt_conf_value_t *uri;
40 nxt_conf_value_t *method;
41 nxt_conf_value_t *headers;
42 nxt_conf_value_t *arguments;
43 nxt_conf_value_t *cookies;
43} nxt_http_route_match_conf_t;
44
45
46typedef struct {
47 u_char *start1;
48 u_char *start2;
49 uint32_t length1;
50 uint32_t length2;

--- 11 unchanged lines hidden (view full) ---

62 uint16_t name_length;
63 uint32_t value_length;
64 u_char *name;
65 u_char *value;
66} nxt_http_name_value_t;
67
68
69typedef struct {
44} nxt_http_route_match_conf_t;
45
46
47typedef struct {
48 u_char *start1;
49 u_char *start2;
50 uint32_t length1;
51 uint32_t length2;

--- 11 unchanged lines hidden (view full) ---

63 uint16_t name_length;
64 uint32_t value_length;
65 u_char *name;
66 u_char *value;
67} nxt_http_name_value_t;
68
69
70typedef struct {
71 uint16_t hash;
72 uint16_t name_length;
73 uint32_t value_length;
74 u_char *name;
75 u_char *value;
76} nxt_http_cookie_t;
77
78
79typedef struct {
70 /* The object must be the first field. */
71 nxt_http_route_object_t object:8;
72 uint32_t items;
73
74 union {
75 uintptr_t offset;
76
77 struct {

--- 42 unchanged lines hidden (view full) ---

120
121
122struct nxt_http_routes_s {
123 uint32_t items;
124 nxt_http_route_t *route[0];
125};
126
127
80 /* The object must be the first field. */
81 nxt_http_route_object_t object:8;
82 uint32_t items;
83
84 union {
85 uintptr_t offset;
86
87 struct {

--- 42 unchanged lines hidden (view full) ---

130
131
132struct nxt_http_routes_s {
133 uint32_t items;
134 nxt_http_route_t *route[0];
135};
136
137
138#define NJS_COOKIE_HASH \
139 (nxt_http_field_hash_end( \
140 nxt_http_field_hash_char( \
141 nxt_http_field_hash_char( \
142 nxt_http_field_hash_char( \
143 nxt_http_field_hash_char( \
144 nxt_http_field_hash_char( \
145 nxt_http_field_hash_char(NXT_HTTP_FIELD_HASH_INIT, \
146 'c'), 'o'), 'o'), 'k'), 'i'), 'e')) & 0xFFFF)
147
148
128static nxt_http_route_t *nxt_http_route_create(nxt_task_t *task,
129 nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
130static nxt_http_route_match_t *nxt_http_route_match_create(nxt_task_t *task,
131 nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
132static nxt_http_route_table_t *nxt_http_route_table_create(nxt_task_t *task,
133 nxt_mp_t *mp, nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
134 nxt_bool_t case_sensitive);
135static nxt_http_route_ruleset_t *nxt_http_route_ruleset_create(nxt_task_t *task,

--- 35 unchanged lines hidden (view full) ---

171static nxt_int_t nxt_http_route_arguments(nxt_http_request_t *r,
172 nxt_http_route_rule_t *rule);
173static nxt_array_t *nxt_http_route_arguments_parse(nxt_http_request_t *r);
174static nxt_http_name_value_t *nxt_http_route_argument(nxt_array_t *array,
175 u_char *name, size_t name_length, uint32_t hash, u_char *start,
176 u_char *end);
177static nxt_int_t nxt_http_route_test_argument(nxt_http_request_t *r,
178 nxt_http_route_rule_t *rule, nxt_array_t *array);
149static nxt_http_route_t *nxt_http_route_create(nxt_task_t *task,
150 nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
151static nxt_http_route_match_t *nxt_http_route_match_create(nxt_task_t *task,
152 nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
153static nxt_http_route_table_t *nxt_http_route_table_create(nxt_task_t *task,
154 nxt_mp_t *mp, nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
155 nxt_bool_t case_sensitive);
156static nxt_http_route_ruleset_t *nxt_http_route_ruleset_create(nxt_task_t *task,

--- 35 unchanged lines hidden (view full) ---

192static nxt_int_t nxt_http_route_arguments(nxt_http_request_t *r,
193 nxt_http_route_rule_t *rule);
194static nxt_array_t *nxt_http_route_arguments_parse(nxt_http_request_t *r);
195static nxt_http_name_value_t *nxt_http_route_argument(nxt_array_t *array,
196 u_char *name, size_t name_length, uint32_t hash, u_char *start,
197 u_char *end);
198static nxt_int_t nxt_http_route_test_argument(nxt_http_request_t *r,
199 nxt_http_route_rule_t *rule, nxt_array_t *array);
200static nxt_int_t nxt_http_route_cookies(nxt_http_request_t *r,
201 nxt_http_route_rule_t *rule);
202static nxt_array_t *nxt_http_route_cookies_parse(nxt_http_request_t *r);
203static nxt_int_t nxt_http_route_cookie_parse(nxt_array_t *cookies,
204 u_char *start, u_char *end);
205static nxt_http_name_value_t *nxt_http_route_cookie(nxt_array_t *array,
206 u_char *name, size_t name_length, u_char *start, u_char *end);
207static nxt_int_t nxt_http_route_test_cookie(nxt_http_request_t *r,
208 nxt_http_route_rule_t *rule, nxt_array_t *array);
179static nxt_int_t nxt_http_route_test_rule(nxt_http_request_t *r,
180 nxt_http_route_rule_t *rule, u_char *start, size_t length);
181static nxt_int_t nxt_http_route_pattern(nxt_http_request_t *r,
182 nxt_http_route_pattern_t *pattern, u_char *start, size_t length);
183static nxt_int_t nxt_http_route_memcmp(u_char *start, u_char *test,
184 size_t length, nxt_bool_t case_sensitive);
185
186

--- 83 unchanged lines hidden (view full) ---

270 offsetof(nxt_http_route_match_conf_t, headers),
271 },
272
273 {
274 nxt_string("arguments"),
275 NXT_CONF_MAP_PTR,
276 offsetof(nxt_http_route_match_conf_t, arguments),
277 },
209static nxt_int_t nxt_http_route_test_rule(nxt_http_request_t *r,
210 nxt_http_route_rule_t *rule, u_char *start, size_t length);
211static nxt_int_t nxt_http_route_pattern(nxt_http_request_t *r,
212 nxt_http_route_pattern_t *pattern, u_char *start, size_t length);
213static nxt_int_t nxt_http_route_memcmp(u_char *start, u_char *test,
214 size_t length, nxt_bool_t case_sensitive);
215
216

--- 83 unchanged lines hidden (view full) ---

300 offsetof(nxt_http_route_match_conf_t, headers),
301 },
302
303 {
304 nxt_string("arguments"),
305 NXT_CONF_MAP_PTR,
306 offsetof(nxt_http_route_match_conf_t, arguments),
307 },
308
309 {
310 nxt_string("cookies"),
311 NXT_CONF_MAP_PTR,
312 offsetof(nxt_http_route_match_conf_t, cookies),
313 },
278};
279
280
281static nxt_http_route_t *
282nxt_http_route_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
283 nxt_conf_value_t *cv)
284{
285 size_t size;

--- 146 unchanged lines hidden (view full) ---

432 if (table == NULL) {
433 return NULL;
434 }
435
436 test->table = table;
437 test++;
438 }
439
314};
315
316
317static nxt_http_route_t *
318nxt_http_route_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
319 nxt_conf_value_t *cv)
320{
321 size_t size;

--- 146 unchanged lines hidden (view full) ---

468 if (table == NULL) {
469 return NULL;
470 }
471
472 test->table = table;
473 test++;
474 }
475
476 if (mtcf.cookies != NULL) {
477 table = nxt_http_route_table_create(task, mp, mtcf.cookies,
478 NXT_HTTP_ROUTE_COOKIE, 0);
479 if (table == NULL) {
480 return NULL;
481 }
482
483 test->table = table;
484 test++;
485 }
486
440 return match;
441}
442
443
444static nxt_http_route_table_t *
445nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp,
446 nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
447 nxt_bool_t case_sensitive)

--- 623 unchanged lines hidden (view full) ---

1071
1072 case NXT_HTTP_ROUTE_HEADER:
1073 return nxt_http_route_header(r, rule);
1074
1075 case NXT_HTTP_ROUTE_ARGUMENT:
1076 return nxt_http_route_arguments(r, rule);
1077
1078 case NXT_HTTP_ROUTE_COOKIE:
487 return match;
488}
489
490
491static nxt_http_route_table_t *
492nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp,
493 nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
494 nxt_bool_t case_sensitive)

--- 623 unchanged lines hidden (view full) ---

1118
1119 case NXT_HTTP_ROUTE_HEADER:
1120 return nxt_http_route_header(r, rule);
1121
1122 case NXT_HTTP_ROUTE_ARGUMENT:
1123 return nxt_http_route_arguments(r, rule);
1124
1125 case NXT_HTTP_ROUTE_COOKIE:
1079 return 0;
1126 return nxt_http_route_cookies(r, rule);
1080
1081 default:
1082 break;
1083 }
1084
1085 p = nxt_pointer_to(r, rule->u.offset);
1086
1087 if (rule->object == NXT_HTTP_ROUTE_STRING) {

--- 191 unchanged lines hidden (view full) ---

1279 nv++;
1280 }
1281
1282 return ret;
1283}
1284
1285
1286static nxt_int_t
1127
1128 default:
1129 break;
1130 }
1131
1132 p = nxt_pointer_to(r, rule->u.offset);
1133
1134 if (rule->object == NXT_HTTP_ROUTE_STRING) {

--- 191 unchanged lines hidden (view full) ---

1326 nv++;
1327 }
1328
1329 return ret;
1330}
1331
1332
1333static nxt_int_t
1334nxt_http_route_cookies(nxt_http_request_t *r, nxt_http_route_rule_t *rule)
1335{
1336 nxt_array_t *cookies;
1337
1338 cookies = nxt_http_route_cookies_parse(r);
1339 if (nxt_slow_path(cookies == NULL)) {
1340 return -1;
1341 }
1342
1343 return nxt_http_route_test_cookie(r, rule, cookies);
1344}
1345
1346
1347static nxt_array_t *
1348nxt_http_route_cookies_parse(nxt_http_request_t *r)
1349{
1350 nxt_int_t ret;
1351 nxt_array_t *cookies;
1352 nxt_http_field_t *f;
1353
1354 if (r->cookies != NULL) {
1355 return r->cookies;
1356 }
1357
1358 cookies = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t));
1359 if (nxt_slow_path(cookies == NULL)) {
1360 return NULL;
1361 }
1362
1363 nxt_list_each(f, r->fields) {
1364
1365 if (f->hash != NJS_COOKIE_HASH
1366 || f->name_length != 6
1367 || nxt_strncasecmp(f->name, (u_char *) "Cookie", 6) != 0)
1368 {
1369 continue;
1370 }
1371
1372 ret = nxt_http_route_cookie_parse(cookies, f->value,
1373 f->value + f->value_length);
1374 if (ret != NXT_OK) {
1375 return NULL;
1376 }
1377
1378 } nxt_list_loop;
1379
1380 r->cookies = cookies;
1381
1382 return cookies;
1383}
1384
1385
1386static nxt_int_t
1387nxt_http_route_cookie_parse(nxt_array_t *cookies, u_char *start, u_char *end)
1388{
1389 size_t name_length;
1390 u_char c, *p, *name;
1391 nxt_http_name_value_t *nv;
1392
1393 name = NULL;
1394 name_length = 0;
1395
1396 for (p = start; p < end; p++) {
1397 c = *p;
1398
1399 if (c == '=') {
1400 while (start[0] == ' ') { start++; }
1401
1402 name_length = p - start;
1403
1404 if (name_length != 0) {
1405 name = start;
1406 }
1407
1408 start = p + 1;
1409
1410 } else if (c == ';') {
1411 if (name != NULL) {
1412 nv = nxt_http_route_cookie(cookies, name, name_length,
1413 start, p);
1414 if (nxt_slow_path(nv == NULL)) {
1415 return NXT_ERROR;
1416 }
1417 }
1418
1419 name = NULL;
1420 start = p + 1;
1421 }
1422 }
1423
1424 if (name != NULL) {
1425 nv = nxt_http_route_cookie(cookies, name, name_length, start, p);
1426 if (nxt_slow_path(nv == NULL)) {
1427 return NXT_ERROR;
1428 }
1429 }
1430
1431 return NXT_OK;
1432}
1433
1434
1435static nxt_http_name_value_t *
1436nxt_http_route_cookie(nxt_array_t *array, u_char *name, size_t name_length,
1437 u_char *start, u_char *end)
1438{
1439 u_char c, *p;
1440 uint32_t hash;
1441 nxt_http_name_value_t *nv;
1442
1443 nv = nxt_array_add(array);
1444 if (nxt_slow_path(nv == NULL)) {
1445 return NULL;
1446 }
1447
1448 nv->name_length = name_length;
1449 nv->name = name;
1450
1451 hash = NXT_HTTP_FIELD_HASH_INIT;
1452
1453 for (p = name; p < name + name_length; p++) {
1454 c = *p;
1455 c = nxt_lowcase(c);
1456 hash = nxt_http_field_hash_char(hash, c);
1457 }
1458
1459 nv->hash = nxt_http_field_hash_end(hash) & 0xFFFF;
1460
1461 while (start < end && end[-1] == ' ') { end--; }
1462
1463 nv->value_length = end - start;
1464 nv->value = start;
1465
1466 return nv;
1467}
1468
1469
1470static nxt_int_t
1471nxt_http_route_test_cookie(nxt_http_request_t *r,
1472 nxt_http_route_rule_t *rule, nxt_array_t *array)
1473{
1474 nxt_bool_t ret;
1475 nxt_http_name_value_t *nv, *end;
1476
1477 ret = 0;
1478
1479 nv = array->elts;
1480 end = nv + array->nelts;
1481
1482 while (nv < end) {
1483
1484 if (rule->u.name.hash == nv->hash
1485 && rule->u.name.length == nv->name_length
1486 && nxt_strncasecmp(rule->u.name.start, nv->name, nv->name_length)
1487 == 0)
1488 {
1489 ret = nxt_http_route_test_rule(r, rule, nv->value,
1490 nv->value_length);
1491 if (ret == 0) {
1492 break;
1493 }
1494 }
1495
1496 nv++;
1497 }
1498
1499 return ret;
1500}
1501
1502
1503static nxt_int_t
1287nxt_http_route_test_rule(nxt_http_request_t *r, nxt_http_route_rule_t *rule,
1288 u_char *start, size_t length)
1289{
1290 nxt_int_t ret;
1291 nxt_http_route_pattern_t *pattern, *end;
1292
1293 ret = 1;
1294 pattern = &rule->pattern[0];

--- 95 unchanged lines hidden ---
1504nxt_http_route_test_rule(nxt_http_request_t *r, nxt_http_route_rule_t *rule,
1505 u_char *start, size_t length)
1506{
1507 nxt_int_t ret;
1508 nxt_http_route_pattern_t *pattern, *end;
1509
1510 ret = 1;
1511 pattern = &rule->pattern[0];

--- 95 unchanged lines hidden ---