mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-27 06:51:04 +08:00
Handle #1459 - deprecate mg_globmatch, introduce mg_match()
This commit is contained in:
parent
768f67ae0a
commit
63b880e624
@ -2273,13 +2273,17 @@ if (mg_vcmp(str, "Hello, world") == 0) {
|
||||
}
|
||||
```
|
||||
|
||||
### mg\_globmatch()
|
||||
### mg\_match()
|
||||
|
||||
```c
|
||||
bool mg_globmatch(const char *pattern, size_t p_len, const char *s, size_t s_len);
|
||||
bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps);
|
||||
```
|
||||
|
||||
Check if string `s` (limited to `s_len` symbols) matches glob pattern `pattern`, (limited to `p_len` symbols).
|
||||
Check if string `str` matches glob pattern `pattern`, and optionally capture
|
||||
wildcards into the provided array `caps`.
|
||||
<span class="badge bg-danger">NOTE: </span> If `caps` is not NULL, then it
|
||||
`caps` array size must be at least the number of wildcard symbols in `pattern`
|
||||
plus 1. Last cap will be initialized to an empty string.
|
||||
The glob pattern matching rules are as follows:
|
||||
|
||||
- `?` matches any single character
|
||||
@ -2288,21 +2292,19 @@ The glob pattern matching rules are as follows:
|
||||
- any other character matches itself
|
||||
|
||||
Parameters:
|
||||
- `pattern` - Pattern to match for
|
||||
- `p_len` - Pattern length
|
||||
- `s` - String to match
|
||||
- `s_len` - String length
|
||||
- `str` - a string to match
|
||||
- `pattern` - a pattern to match against
|
||||
- `caps` - an optional array of captures for wildcard symbols `?`, `*`, '#'
|
||||
|
||||
Return value: `true` if matches, `false` otherwise
|
||||
|
||||
Usage example:
|
||||
|
||||
```c
|
||||
struct mg_str pattern = mg_str("#, ?????");
|
||||
struct mg_str s = mg_str("Hello, world");
|
||||
|
||||
if (mg_globmatch(pattern.ptr, pattern.len, s.otr, s.len)) {
|
||||
// Match
|
||||
// Assume that hm->uri holds /foo/bar. Then we can match the requested URI:
|
||||
struct mg_str caps[2];
|
||||
if (mg_match(hm->uri, mg_str("/*/*"))) {
|
||||
// caps[0] holds `foo`, caps[1] holds `bar`.
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -59,7 +59,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
LIST_ADD_HEAD(struct sub, &s_subs, sub);
|
||||
LOG(LL_INFO,
|
||||
("SUB %p [%.*s]", c->fd, (int) sub->topic.len, sub->topic.ptr));
|
||||
// Change '+' to '*' for topic matching using mg_globmatch
|
||||
// Change '+' to '*' for topic matching using mg_match
|
||||
for (size_t i = 0; i < sub->topic.len; i++) {
|
||||
if (sub->topic.ptr[i] == '+') ((char *) sub->topic.ptr)[i] = '*';
|
||||
}
|
||||
@ -76,8 +76,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
LOG(LL_INFO, ("PUB %p [%.*s] -> [%.*s]", c->fd, (int) mm->data.len,
|
||||
mm->data.ptr, (int) mm->topic.len, mm->topic.ptr));
|
||||
for (struct sub *sub = s_subs; sub != NULL; sub = sub->next) {
|
||||
if (mg_globmatch(sub->topic.ptr, sub->topic.len, mm->topic.ptr,
|
||||
mm->topic.len)) {
|
||||
if (mg_match(mm->topic, sub->topic, NULL)) {
|
||||
mg_mqtt_pub(sub->c, mm->topic, mm->data, 1, false);
|
||||
}
|
||||
}
|
||||
|
101
mongoose.c
101
mongoose.c
@ -1760,7 +1760,7 @@ struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v) {
|
||||
}
|
||||
|
||||
bool mg_http_match_uri(const struct mg_http_message *hm, const char *glob) {
|
||||
return mg_globmatch(glob, strlen(glob), hm->uri.ptr, hm->uri.len);
|
||||
return mg_match(hm->uri, mg_str(glob), NULL);
|
||||
}
|
||||
|
||||
static size_t get_chunk_length(const char *buf, size_t len, size_t *ll) {
|
||||
@ -3870,6 +3870,65 @@ struct mg_str mg_strstrip(struct mg_str s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
|
||||
size_t i = 0, j = 0, ni = 0, nj = 0;
|
||||
if (caps) caps->ptr = NULL, caps->len = 0;
|
||||
while (i < p.len || j < s.len) {
|
||||
if (i < p.len && j < s.len && (p.ptr[i] == '?' || s.ptr[j] == p.ptr[i])) {
|
||||
if (caps == NULL) {
|
||||
} else if (p.ptr[i] == '?') {
|
||||
caps->ptr = &s.ptr[j], caps->len = 1; // Finalize `?` cap
|
||||
caps++, caps->ptr = NULL, caps->len = 0; // Init next cap
|
||||
} else if (caps->ptr != NULL && caps->len == 0) {
|
||||
caps->len = (size_t) (&s.ptr[j] - caps->ptr); // Finalize current cap
|
||||
caps++, caps->len = 0, caps->ptr = NULL; // Init next cap
|
||||
}
|
||||
i++, j++;
|
||||
} else if (i < p.len && (p.ptr[i] == '*' || p.ptr[i] == '#')) {
|
||||
if (caps && !caps->ptr) caps->len = 0, caps->ptr = &s.ptr[j]; // Init cap
|
||||
ni = i++, nj = j + 1;
|
||||
} else if (nj > 0 && nj <= s.len && (p.ptr[ni] == '#' || s.ptr[j] != '/')) {
|
||||
i = ni, j = nj;
|
||||
if (caps && caps->ptr == NULL && caps->len == 0) {
|
||||
caps--, caps->len = 0; // Restart previous cap
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (caps && caps->ptr && caps->len == 0) {
|
||||
caps->len = (size_t) (&s.ptr[j] - caps->ptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
|
||||
return mg_match(mg_str_n(s2, n2), mg_str_n(s1, n1), NULL);
|
||||
}
|
||||
|
||||
static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff,
|
||||
size_t *klen, size_t *voff, size_t *vlen) {
|
||||
size_t kvlen, kl;
|
||||
for (kvlen = 0; ofs + kvlen < n && s[ofs + kvlen] != ',';) kvlen++;
|
||||
for (kl = 0; kl < kvlen && s[ofs + kl] != '=';) kl++;
|
||||
if (koff != NULL) *koff = ofs;
|
||||
if (klen != NULL) *klen = kl;
|
||||
if (voff != NULL) *voff = kl < kvlen ? ofs + kl + 1 : 0;
|
||||
if (vlen != NULL) *vlen = kl < kvlen ? kvlen - kl - 1 : 0;
|
||||
ofs += kvlen + 1;
|
||||
return ofs > n ? n : ofs;
|
||||
}
|
||||
|
||||
bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
|
||||
size_t koff = 0, klen = 0, voff = 0, vlen = 0, off = 0;
|
||||
if (s->ptr == NULL || s->len == 0) return 0;
|
||||
off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen);
|
||||
if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
|
||||
if (v != NULL) *v = mg_str_n(s->ptr + voff, vlen);
|
||||
*s = mg_str_n(s->ptr + off, s->len - off);
|
||||
return off > 0;
|
||||
}
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "src/timer.c"
|
||||
#endif
|
||||
@ -4421,46 +4480,6 @@ void mg_random(void *buf, size_t len) {
|
||||
}
|
||||
#endif
|
||||
|
||||
bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
|
||||
size_t i = 0, j = 0, ni = 0, nj = 0;
|
||||
while (i < n1 || j < n2) {
|
||||
if (i < n1 && j < n2 && (s1[i] == '?' || s2[j] == s1[i])) {
|
||||
i++, j++;
|
||||
} else if (i < n1 && (s1[i] == '*' || s1[i] == '#')) {
|
||||
ni = i, nj = j + 1, i++;
|
||||
} else if (nj > 0 && nj <= n2 && (s1[ni] == '#' || s2[j] != '/')) {
|
||||
i = ni, j = nj;
|
||||
} else {
|
||||
// printf(">>: [%s] [%s] %d %d %d %d\n", s1, s2, i, j, ni, nj);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff,
|
||||
size_t *klen, size_t *voff, size_t *vlen) {
|
||||
size_t kvlen, kl;
|
||||
for (kvlen = 0; ofs + kvlen < n && s[ofs + kvlen] != ',';) kvlen++;
|
||||
for (kl = 0; kl < kvlen && s[ofs + kl] != '=';) kl++;
|
||||
if (koff != NULL) *koff = ofs;
|
||||
if (klen != NULL) *klen = kl;
|
||||
if (voff != NULL) *voff = kl < kvlen ? ofs + kl + 1 : 0;
|
||||
if (vlen != NULL) *vlen = kl < kvlen ? kvlen - kl - 1 : 0;
|
||||
ofs += kvlen + 1;
|
||||
return ofs > n ? n : ofs;
|
||||
}
|
||||
|
||||
bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
|
||||
size_t koff = 0, klen = 0, voff = 0, vlen = 0, off = 0;
|
||||
if (s->ptr == NULL || s->len == 0) return 0;
|
||||
off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen);
|
||||
if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
|
||||
if (v != NULL) *v = mg_str_n(s->ptr + voff, vlen);
|
||||
*s = mg_str_n(s->ptr + off, s->len - off);
|
||||
return off > 0;
|
||||
}
|
||||
|
||||
uint32_t mg_ntohl(uint32_t net) {
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
memcpy(&data, &net, sizeof(data));
|
||||
|
@ -580,6 +580,9 @@ int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
|
||||
struct mg_str mg_strstrip(struct mg_str s);
|
||||
struct mg_str mg_strdup(const struct mg_str s);
|
||||
const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
|
||||
bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps);
|
||||
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
|
||||
bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
||||
|
||||
|
||||
|
||||
@ -676,8 +679,6 @@ bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...);
|
||||
|
||||
|
||||
void mg_random(void *buf, size_t len);
|
||||
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
|
||||
bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
||||
uint16_t mg_ntohs(uint16_t net);
|
||||
uint32_t mg_ntohl(uint32_t net);
|
||||
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
|
||||
|
@ -808,7 +808,7 @@ struct mg_str mg_http_get_header_var(struct mg_str s, struct mg_str v) {
|
||||
}
|
||||
|
||||
bool mg_http_match_uri(const struct mg_http_message *hm, const char *glob) {
|
||||
return mg_globmatch(glob, strlen(glob), hm->uri.ptr, hm->uri.len);
|
||||
return mg_match(hm->uri, mg_str(glob), NULL);
|
||||
}
|
||||
|
||||
static size_t get_chunk_length(const char *buf, size_t len, size_t *ll) {
|
||||
|
59
src/str.c
59
src/str.c
@ -86,3 +86,62 @@ struct mg_str mg_strstrip(struct mg_str s) {
|
||||
while (s.len > 0 && isspace((int) *(s.ptr + s.len - 1))) s.len--;
|
||||
return s;
|
||||
}
|
||||
|
||||
bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
|
||||
size_t i = 0, j = 0, ni = 0, nj = 0;
|
||||
if (caps) caps->ptr = NULL, caps->len = 0;
|
||||
while (i < p.len || j < s.len) {
|
||||
if (i < p.len && j < s.len && (p.ptr[i] == '?' || s.ptr[j] == p.ptr[i])) {
|
||||
if (caps == NULL) {
|
||||
} else if (p.ptr[i] == '?') {
|
||||
caps->ptr = &s.ptr[j], caps->len = 1; // Finalize `?` cap
|
||||
caps++, caps->ptr = NULL, caps->len = 0; // Init next cap
|
||||
} else if (caps->ptr != NULL && caps->len == 0) {
|
||||
caps->len = (size_t) (&s.ptr[j] - caps->ptr); // Finalize current cap
|
||||
caps++, caps->len = 0, caps->ptr = NULL; // Init next cap
|
||||
}
|
||||
i++, j++;
|
||||
} else if (i < p.len && (p.ptr[i] == '*' || p.ptr[i] == '#')) {
|
||||
if (caps && !caps->ptr) caps->len = 0, caps->ptr = &s.ptr[j]; // Init cap
|
||||
ni = i++, nj = j + 1;
|
||||
} else if (nj > 0 && nj <= s.len && (p.ptr[ni] == '#' || s.ptr[j] != '/')) {
|
||||
i = ni, j = nj;
|
||||
if (caps && caps->ptr == NULL && caps->len == 0) {
|
||||
caps--, caps->len = 0; // Restart previous cap
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (caps && caps->ptr && caps->len == 0) {
|
||||
caps->len = (size_t) (&s.ptr[j] - caps->ptr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
|
||||
return mg_match(mg_str_n(s2, n2), mg_str_n(s1, n1), NULL);
|
||||
}
|
||||
|
||||
static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff,
|
||||
size_t *klen, size_t *voff, size_t *vlen) {
|
||||
size_t kvlen, kl;
|
||||
for (kvlen = 0; ofs + kvlen < n && s[ofs + kvlen] != ',';) kvlen++;
|
||||
for (kl = 0; kl < kvlen && s[ofs + kl] != '=';) kl++;
|
||||
if (koff != NULL) *koff = ofs;
|
||||
if (klen != NULL) *klen = kl;
|
||||
if (voff != NULL) *voff = kl < kvlen ? ofs + kl + 1 : 0;
|
||||
if (vlen != NULL) *vlen = kl < kvlen ? kvlen - kl - 1 : 0;
|
||||
ofs += kvlen + 1;
|
||||
return ofs > n ? n : ofs;
|
||||
}
|
||||
|
||||
bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
|
||||
size_t koff = 0, klen = 0, voff = 0, vlen = 0, off = 0;
|
||||
if (s->ptr == NULL || s->len == 0) return 0;
|
||||
off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen);
|
||||
if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
|
||||
if (v != NULL) *v = mg_str_n(s->ptr + voff, vlen);
|
||||
*s = mg_str_n(s->ptr + off, s->len - off);
|
||||
return off > 0;
|
||||
}
|
||||
|
@ -27,3 +27,6 @@ int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
|
||||
struct mg_str mg_strstrip(struct mg_str s);
|
||||
struct mg_str mg_strdup(const struct mg_str s);
|
||||
const char *mg_strstr(const struct mg_str haystack, const struct mg_str needle);
|
||||
bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps);
|
||||
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
|
||||
bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
||||
|
40
src/util.c
40
src/util.c
@ -25,46 +25,6 @@ void mg_random(void *buf, size_t len) {
|
||||
}
|
||||
#endif
|
||||
|
||||
bool mg_globmatch(const char *s1, size_t n1, const char *s2, size_t n2) {
|
||||
size_t i = 0, j = 0, ni = 0, nj = 0;
|
||||
while (i < n1 || j < n2) {
|
||||
if (i < n1 && j < n2 && (s1[i] == '?' || s2[j] == s1[i])) {
|
||||
i++, j++;
|
||||
} else if (i < n1 && (s1[i] == '*' || s1[i] == '#')) {
|
||||
ni = i, nj = j + 1, i++;
|
||||
} else if (nj > 0 && nj <= n2 && (s1[ni] == '#' || s2[j] != '/')) {
|
||||
i = ni, j = nj;
|
||||
} else {
|
||||
// printf(">>: [%s] [%s] %d %d %d %d\n", s1, s2, i, j, ni, nj);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff,
|
||||
size_t *klen, size_t *voff, size_t *vlen) {
|
||||
size_t kvlen, kl;
|
||||
for (kvlen = 0; ofs + kvlen < n && s[ofs + kvlen] != ',';) kvlen++;
|
||||
for (kl = 0; kl < kvlen && s[ofs + kl] != '=';) kl++;
|
||||
if (koff != NULL) *koff = ofs;
|
||||
if (klen != NULL) *klen = kl;
|
||||
if (voff != NULL) *voff = kl < kvlen ? ofs + kl + 1 : 0;
|
||||
if (vlen != NULL) *vlen = kl < kvlen ? kvlen - kl - 1 : 0;
|
||||
ofs += kvlen + 1;
|
||||
return ofs > n ? n : ofs;
|
||||
}
|
||||
|
||||
bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) {
|
||||
size_t koff = 0, klen = 0, voff = 0, vlen = 0, off = 0;
|
||||
if (s->ptr == NULL || s->len == 0) return 0;
|
||||
off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen);
|
||||
if (k != NULL) *k = mg_str_n(s->ptr + koff, klen);
|
||||
if (v != NULL) *v = mg_str_n(s->ptr + voff, vlen);
|
||||
*s = mg_str_n(s->ptr + off, s->len - off);
|
||||
return off > 0;
|
||||
}
|
||||
|
||||
uint32_t mg_ntohl(uint32_t net) {
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
memcpy(&data, &net, sizeof(data));
|
||||
|
@ -5,8 +5,6 @@
|
||||
#include "str.h"
|
||||
|
||||
void mg_random(void *buf, size_t len);
|
||||
bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n);
|
||||
bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v);
|
||||
uint16_t mg_ntohs(uint16_t net);
|
||||
uint32_t mg_ntohl(uint32_t net);
|
||||
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
|
||||
|
@ -48,6 +48,47 @@ static void test_globmatch(void) {
|
||||
ASSERT(mg_globmatch("#.shtml", 7, "./ssi/index.shtml", 17) == 1);
|
||||
ASSERT(mg_globmatch("#aa#bb#", 7, "caabba", 6) == 1);
|
||||
ASSERT(mg_globmatch("#aa#bb#", 7, "caabxa", 6) == 0);
|
||||
ASSERT(mg_globmatch("a*b*c", 5, "a__b_c", 6) == 1);
|
||||
|
||||
{
|
||||
struct mg_str caps[3];
|
||||
ASSERT(mg_match(mg_str("//a.c"), mg_str("#.c"), NULL) == true);
|
||||
ASSERT(mg_match(mg_str("a"), mg_str("#"), caps) == true);
|
||||
ASSERT(mg_strcmp(caps[0], mg_str("a")) == 0);
|
||||
ASSERT(mg_match(mg_str("//a.c"), mg_str("#.c"), caps) == true);
|
||||
ASSERT(mg_match(mg_str("a_b_c_"), mg_str("a*b*c"), caps) == false);
|
||||
ASSERT(mg_match(mg_str("a__b_c"), mg_str("a*b*c"), caps) == true);
|
||||
ASSERT(mg_strcmp(caps[0], mg_str("__")) == 0);
|
||||
ASSERT(mg_strcmp(caps[1], mg_str("_")) == 0);
|
||||
ASSERT(mg_match(mg_str("a_b_c__c"), mg_str("a*b*c"), caps) == true);
|
||||
ASSERT(mg_strcmp(caps[0], mg_str("_")) == 0);
|
||||
ASSERT(mg_strcmp(caps[1], mg_str("_c__")) == 0);
|
||||
ASSERT(mg_match(mg_str("a_xb_.c__c"), mg_str("a*b*c"), caps) == true);
|
||||
ASSERT(mg_strcmp(caps[0], mg_str("_x")) == 0);
|
||||
ASSERT(mg_strcmp(caps[1], mg_str("_.c__")) == 0);
|
||||
ASSERT(mg_match(mg_str("a"), mg_str("#a"), caps) == true);
|
||||
ASSERT(mg_strcmp(caps[0], mg_str("")) == 0);
|
||||
|
||||
ASSERT(mg_match(mg_str(".aa..b...b"), mg_str("#a#b"), caps) == true);
|
||||
ASSERT(mg_strcmp(caps[0], mg_str(".")) == 0);
|
||||
ASSERT(mg_strcmp(caps[1], mg_str("a..b...")) == 0);
|
||||
ASSERT(mg_strcmp(caps[2], mg_str("")) == 0);
|
||||
|
||||
ASSERT(mg_match(mg_str("/foo/bar"), mg_str("/*/*"), caps) == true);
|
||||
ASSERT(mg_strcmp(caps[0], mg_str("foo")) == 0);
|
||||
ASSERT(mg_strcmp(caps[1], mg_str("bar")) == 0);
|
||||
ASSERT(mg_strcmp(caps[2], mg_str("")) == 0);
|
||||
|
||||
ASSERT(mg_match(mg_str("/foo/"), mg_str("/*/*"), caps) == true);
|
||||
ASSERT(mg_strcmp(caps[0], mg_str("foo")) == 0);
|
||||
ASSERT(mg_strcmp(caps[1], mg_str("")) == 0);
|
||||
ASSERT(mg_strcmp(caps[2], mg_str("")) == 0);
|
||||
|
||||
ASSERT(mg_match(mg_str("abc"), mg_str("?#"), caps) == true);
|
||||
ASSERT(mg_strcmp(caps[0], mg_str("a")) == 0);
|
||||
ASSERT(mg_strcmp(caps[1], mg_str("bc")) == 0);
|
||||
ASSERT(mg_strcmp(caps[2], mg_str("")) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_commalist(void) {
|
||||
@ -1655,6 +1696,7 @@ static void test_get_header_var(void) {
|
||||
|
||||
int main(void) {
|
||||
mg_log_set("3");
|
||||
test_globmatch();
|
||||
test_get_header_var();
|
||||
test_rewrites();
|
||||
test_check_ip_acl();
|
||||
@ -1674,7 +1716,6 @@ int main(void) {
|
||||
test_iobuf();
|
||||
test_commalist();
|
||||
test_base64();
|
||||
test_globmatch();
|
||||
test_http_get_var();
|
||||
test_tls();
|
||||
test_ws();
|
||||
|
Loading…
x
Reference in New Issue
Block a user