问题
I have following acl rules to check the range of my url_param value.
acl small urlp_val(uid) le 311111111111000000
acl medium urlp_val(uid) 311111111111000001:311111111111001000
acl large urlp_val(uid) ge 311111111111001001
The number are 64 bit integers. This comparison doesn't seem to be working. It always redirect to only one instance. If I decrease the numbers to a range of say 1 to 100, it works well. Does it not support 64 bit numbers or am I doing something stupid/silly here?
回答1:
The documentation always uses "int" and "integer" to talk about this type. If you check the source code, you'll see that smp_fetch_url_param_val uses strl2ic which returns an int
, not a long
.
So no, you can't extract 64bit values with urlp_val
.
回答2:
I am had a similar task. I solved it by cutting off the last 6 characters from a large number and comparing only the first part.
# my case: if some_id >= 9089000000 use backend_2
acl is_number_long urlp_reg('some_id') '^\d{7,}$'
acl is_first_part_great urlp('some_id'),regsub('\d{6}$','') -m int gt 9088
use_backend backend_2 if is_number_long is_first_part_great
default_backend backend_1
You can try something like this:
# some_id = 311111111111000000 -> first_part = 311111111, last_part = 111000000
acl is_number_long urlp_reg('some_id') '^\d{10,}$'
acl is_first_part_gt urlp('some_id'),regsub('\d{9}$','') -m int gt 311111111
acl is_first_part_eq urlp('some_id'),regsub('\d{9}$','') -m int eq 311111111
acl is_last_part_gt urlp('some_id'),regsub('^.*(\d{9})$','\1') -m int gt 111000000
acl is_last_part_lt urlp('some_id'),regsub('^.*(\d{9})$','\1') -m int lt 111001001
use_backend backend_3 if is_number_long is_first_part_gt # large
use_backend backend_3 if is_number_long is_first_part_eq !is_last_part_lt # large
use_backend backend_2 if is_number_long is_first_part_eq is_last_part_gt is_last_part_lt # medium
default_backend backend_1 # small
来源:https://stackoverflow.com/questions/40900901/64-bit-integer-comparison-in-haproxy-acl-rule