TEST(http_match, method_eq) { int match_id; MatchEntry *e1, *e2; size_t len = FIELD_SIZEOF(TfwHttpMatchArg, method); e1 = tfw_http_match_entry_new(test_mlst, MatchEntry, rule, len); e1->test_id = 42, e1->rule.field = TFW_HTTP_MATCH_F_METHOD; e1->rule.op = TFW_HTTP_MATCH_O_EQ; e1->rule.arg.type = TFW_HTTP_MATCH_A_METHOD; e1->rule.arg.len = len; e1->rule.arg.method = TFW_HTTP_METH_POST; e2 = tfw_http_match_entry_new(test_mlst, MatchEntry, rule, len); e2->test_id = 43, e2->rule.field = TFW_HTTP_MATCH_F_METHOD; e2->rule.op = TFW_HTTP_MATCH_O_EQ; e2->rule.arg.type = TFW_HTTP_MATCH_A_METHOD; e2->rule.arg.len = len; e2->rule.arg.method = TFW_HTTP_METH_GET; test_req->method = TFW_HTTP_METH_HEAD; match_id = test_mlst_match(); EXPECT_EQ(-1, match_id); test_req->method = TFW_HTTP_METH_GET; match_id = test_mlst_match(); EXPECT_EQ(43, match_id); test_req->method = TFW_HTTP_METH_POST; match_id = test_mlst_match(); EXPECT_EQ(42, match_id); }
static void test_mlst_add(int test_id, tfw_http_match_fld_t req_field, tfw_http_match_op_t op, const char *str_arg) { MatchEntry *e; size_t len = strlen(str_arg); e = tfw_http_match_entry_new(test_mlst, MatchEntry, rule, len); e->test_id = test_id; e->rule.field = req_field; e->rule.op = op; e->rule.arg.type = TFW_HTTP_MATCH_A_STR; e->rule.arg.len = len; memcpy(e->rule.arg.str, str_arg, len); }
/** * Handle a "match" entry within "sched_http_rules" section, e.g.: * sched_http_rules { * match group1 uri prefix "/foo"; * match group2 host eq "example.com"; * } * * This callback is invoked for every such "match" entry. * It resolves name of the group, parses the rule and adds the entry to the * tfw_sched_http_rules list. * * Syntax: * +------------------------ a reference to "srv_group"; * | +------------------ HTTP request field * | | +------------ operator (eq, prefix, substr, etc) * | | | +---- argument for the operator (any string) * | | | | * V V V V * match group3 uri prefix "/foo/bar/baz.html" backup=group4 * ^ * | * a backup "srv_group" (optional)----+ * */ static int tfw_sched_http_cfg_handle_match(TfwCfgSpec *cs, TfwCfgEntry *e) { int r; size_t arg_size; TfwSchedHttpRule *rule; tfw_http_match_op_t op; tfw_http_match_fld_t field; tfw_http_match_arg_t type; TfwSrvGroup *main_sg, *backup_sg; const char *in_main_sg, *in_field, *in_op, *in_arg, *in_backup_sg; r = tfw_cfg_check_val_n(e, 4); if (r) return r; in_main_sg = e->vals[0]; in_field = e->vals[1]; in_op = e->vals[2]; in_arg = e->vals[3]; in_backup_sg = tfw_cfg_get_attr(e, "backup", NULL); main_sg = tfw_sg_lookup(in_main_sg); if (!main_sg) { ERR("srv_group is not found: '%s'\n", in_main_sg); return -EINVAL; } if (!in_backup_sg) { backup_sg = NULL; } else { backup_sg = tfw_sg_lookup(in_backup_sg); if (!backup_sg) { ERR("backup srv_group is not found: '%s'\n", in_backup_sg); return -EINVAL; } } r = tfw_cfg_map_enum(tfw_sched_http_cfg_field_enum, in_field, &field); if (r) { ERR("invalid HTTP request field: '%s'\n", in_field); return -EINVAL; } r = tfw_cfg_map_enum(tfw_sched_http_cfg_op_enum, in_op, &op); if (r) { ERR("invalid matching operator: '%s'\n", in_op); return -EINVAL; } arg_size = strlen(in_arg) + 1; type = tfw_sched_http_cfg_arg_tbl[field]; rule = tfw_http_match_entry_new(tfw_sched_http_rules, TfwSchedHttpRule, rule, arg_size); if (!rule) { ERR("can't allocate memory for parsed rule\n"); return -ENOMEM; } DBG("parsed rule: match '%s'=%p '%s'=%d '%s'=%d '%s'\n", in_main_sg, main_sg, in_field, field, in_op, op, in_arg); if (type == TFW_HTTP_MATCH_A_STR || type == TFW_HTTP_MATCH_A_WILDCARD) { tfw_http_match_rule_init(&rule->rule, field, op, type, in_arg); } else { BUG(); // TODO: parsing not string matching rules } rule->main_sg = main_sg; rule->backup_sg = backup_sg; return 0; }