mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-28 12:30:58 +00:00
cleanup 'str' API
This commit is contained in:
1 parent
6c7672f4af
commit
3c531897b6
20 files changed
+350
-400
No files matched your search
+1
-1
@@ -32,7 +32,7 @@
|
||||
#define calloc(a, b) mg_calloc(a, b)
|
||||
#define free(a) vPortFree(a)
|
||||
#define malloc(a) pvPortMalloc(a)
|
||||
#define strdup(s) ((char *) mg_strdup(mg_str(s)).buf)
|
||||
#define strdup(s) mg_mprintf("%s", s)
|
||||
|
||||
// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib
|
||||
static inline void *mg_calloc(size_t cnt, size_t size) {
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ extern uint32_t rt_time_get(void);
|
||||
#include "cmsis_os2.h" // keep this include
|
||||
#endif
|
||||
|
||||
#define strdup(s) ((char *) mg_strdup(mg_str(s)).buf)
|
||||
#define strdup(s) mg_mprintf("%s", s)
|
||||
|
||||
#if defined(__ARMCC_VERSION)
|
||||
#define mode_t size_t
|
||||
|
||||
+33
-19
@@ -1,7 +1,7 @@
|
||||
#include "http.h"
|
||||
#include "arch.h"
|
||||
#include "base64.h"
|
||||
#include "fmt.h"
|
||||
#include "http.h"
|
||||
#include "json.h"
|
||||
#include "log.h"
|
||||
#include "net.h"
|
||||
@@ -11,6 +11,17 @@
|
||||
#include "version.h"
|
||||
#include "ws.h"
|
||||
|
||||
static int mg_ncasecmp(const char *s1, const char *s2, size_t len) {
|
||||
int diff = 0;
|
||||
if (len > 0) do {
|
||||
char c = *s1++, d = *s2++;
|
||||
if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
|
||||
if (d >= 'A' && d <= 'Z') d += 'a' - 'A';
|
||||
diff = c - d;
|
||||
} while (diff == 0 && s1[-1] != '\0' && --len > 0);
|
||||
return diff;
|
||||
}
|
||||
|
||||
bool mg_to_size_t(struct mg_str str, size_t *val);
|
||||
bool mg_to_size_t(struct mg_str str, size_t *val) {
|
||||
size_t i = 0, max = (size_t) -1, max2 = max / 10, result = 0, ndigits = 0;
|
||||
@@ -301,15 +312,15 @@ int mg_http_parse(const char *s, size_t len, struct mg_http_message *hm) {
|
||||
// and method is not (PUT or POST) then reset body length to zero.
|
||||
is_response = mg_ncasecmp(hm->method.buf, "HTTP/", 5) == 0;
|
||||
if (hm->body.len == (size_t) ~0 && !is_response &&
|
||||
mg_vcasecmp(&hm->method, "PUT") != 0 &&
|
||||
mg_vcasecmp(&hm->method, "POST") != 0) {
|
||||
mg_strcasecmp(hm->method, mg_str("PUT")) != 0 &&
|
||||
mg_strcasecmp(hm->method, mg_str("POST")) != 0) {
|
||||
hm->body.len = 0;
|
||||
hm->message.len = (size_t) req_len;
|
||||
}
|
||||
|
||||
// The 204 (No content) responses also have 0 body length
|
||||
if (hm->body.len == (size_t) ~0 && is_response &&
|
||||
mg_vcasecmp(&hm->uri, "204") == 0) {
|
||||
mg_strcasecmp(hm->uri, mg_str("204")) == 0) {
|
||||
hm->body.len = 0;
|
||||
hm->message.len = (size_t) req_len;
|
||||
}
|
||||
@@ -560,10 +571,14 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
|
||||
if (path != NULL) {
|
||||
// If a browser sends us "Accept-Encoding: gzip", try to open .gz first
|
||||
struct mg_str *ae = mg_http_get_header(hm, "Accept-Encoding");
|
||||
if (ae != NULL && mg_strstr(*ae, mg_str("gzip")) != NULL) {
|
||||
mg_snprintf(tmp, sizeof(tmp), "%s.gz", path);
|
||||
fd = mg_fs_open(fs, tmp, MG_FS_READ);
|
||||
if (fd != NULL) gzip = true, path = tmp;
|
||||
if (ae != NULL) {
|
||||
char *ae_ = mg_mprintf("%.*s", ae->len, ae->buf);
|
||||
if (strstr(ae_, "gzip") != NULL) {
|
||||
mg_snprintf(tmp, sizeof(tmp), "%s.gz", path);
|
||||
fd = mg_fs_open(fs, tmp, MG_FS_READ);
|
||||
if (fd != NULL) gzip = true, path = tmp;
|
||||
}
|
||||
free(ae_);
|
||||
}
|
||||
// No luck opening .gz? Open what we've told to open
|
||||
if (fd == NULL) fd = mg_fs_open(fs, path, MG_FS_READ);
|
||||
@@ -582,7 +597,7 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
|
||||
// NOTE: mg_http_etag() call should go first!
|
||||
} else if (mg_http_etag(etag, sizeof(etag), size, mtime) != NULL &&
|
||||
(inm = mg_http_get_header(hm, "If-None-Match")) != NULL &&
|
||||
mg_vcasecmp(inm, etag) == 0) {
|
||||
mg_strcasecmp(*inm, mg_str(etag)) == 0) {
|
||||
mg_fs_close(fd);
|
||||
mg_http_reply(c, 304, opts->extra_headers, "");
|
||||
} else {
|
||||
@@ -619,7 +634,7 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
|
||||
status, mg_http_status_code_str(status), (int) mime.len, mime.buf,
|
||||
etag, (uint64_t) cl, gzip ? "Content-Encoding: gzip\r\n" : "",
|
||||
range, opts->extra_headers ? opts->extra_headers : "");
|
||||
if (mg_vcasecmp(&hm->method, "HEAD") == 0) {
|
||||
if (mg_strcasecmp(hm->method, mg_str("HEAD")) == 0) {
|
||||
c->is_draining = 1;
|
||||
c->is_resp = 0;
|
||||
mg_fs_close(fd);
|
||||
@@ -775,7 +790,8 @@ static int uri_to_path2(struct mg_connection *c, struct mg_http_message *hm,
|
||||
}
|
||||
n = strlen(path);
|
||||
while (n > 1 && path[n - 1] == '/') path[--n] = 0; // Trim trailing slashes
|
||||
flags = mg_vcmp(&hm->uri, "/") == 0 ? MG_FS_DIR : fs->st(path, NULL, NULL);
|
||||
flags = mg_strcmp(hm->uri, mg_str("/")) == 0 ? MG_FS_DIR
|
||||
: fs->st(path, NULL, NULL);
|
||||
MG_VERBOSE(("%lu %.*s -> %s %d", c->id, (int) hm->uri.len, hm->uri.buf, path,
|
||||
flags));
|
||||
if (flags == 0) {
|
||||
@@ -838,8 +854,7 @@ void mg_http_serve_dir(struct mg_connection *c, struct mg_http_message *hm,
|
||||
#else
|
||||
mg_http_reply(c, 403, "", "Forbidden\n");
|
||||
#endif
|
||||
} else if (flags && sp != NULL &&
|
||||
mg_globmatch(sp, strlen(sp), path, strlen(path))) {
|
||||
} else if (flags && sp != NULL && mg_match(mg_str(path), mg_str(sp), NULL)) {
|
||||
mg_http_serve_ssi(c, opts->root_dir, path);
|
||||
} else {
|
||||
mg_http_serve_file(c, hm, path, opts);
|
||||
@@ -859,9 +874,8 @@ size_t mg_url_encode(const char *s, size_t sl, char *buf, size_t len) {
|
||||
if (mg_is_url_safe(c)) {
|
||||
buf[n++] = s[i];
|
||||
} else {
|
||||
buf[n++] = '%';
|
||||
mg_hex(&s[i], 1, &buf[n]);
|
||||
n += 2;
|
||||
mg_snprintf(&buf[n], 4, "%%%M", mg_print_hex, 1, &s[i]);
|
||||
n += 3;
|
||||
}
|
||||
}
|
||||
if (len > 0 && n < len - 1) buf[n] = '\0'; // Null-terminate the destination
|
||||
@@ -1007,7 +1021,7 @@ static void http_cb(struct mg_connection *c, int ev, void *ev_data) {
|
||||
hm.body.len = hm.message.len - (size_t) (hm.body.buf - hm.message.buf);
|
||||
}
|
||||
if ((te = mg_http_get_header(&hm, "Transfer-Encoding")) != NULL) {
|
||||
if (mg_vcasecmp(te, "chunked") == 0) {
|
||||
if (mg_strcasecmp(*te, mg_str("chunked")) == 0) {
|
||||
is_chunked = true;
|
||||
} else {
|
||||
mg_error(c, "Invalid Transfer-Encoding"); // See #2460
|
||||
@@ -1018,8 +1032,8 @@ static void http_cb(struct mg_connection *c, int ev, void *ev_data) {
|
||||
// Content-length
|
||||
bool is_response = mg_ncasecmp(hm.method.buf, "HTTP/", 5) == 0;
|
||||
bool require_content_len = false;
|
||||
if (!is_response && (mg_vcasecmp(&hm.method, "POST") == 0 ||
|
||||
mg_vcasecmp(&hm.method, "PUT") == 0)) {
|
||||
if (!is_response && (mg_strcasecmp(hm.method, mg_str("POST")) == 0 ||
|
||||
mg_strcasecmp(hm.method, mg_str("PUT")) == 0)) {
|
||||
// POST and PUT should include an entity body. Therefore, they should
|
||||
// contain a Content-length header. Other requests can also contain a
|
||||
// body, but their content has no defined semantics (RFC 7231)
|
||||
|
||||
+2
-3
@@ -254,14 +254,13 @@ size_t mg_mqtt_next_prop(struct mg_mqtt_message *msg, struct mg_mqtt_prop *prop,
|
||||
}
|
||||
|
||||
void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
|
||||
char rnd[10], client_id[21];
|
||||
char client_id[21];
|
||||
struct mg_str cid = opts->client_id;
|
||||
size_t total_len = 7 + 1 + 2 + 2;
|
||||
uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', opts->version, 0};
|
||||
|
||||
if (cid.len == 0) {
|
||||
mg_random(rnd, sizeof(rnd));
|
||||
mg_hex(rnd, sizeof(rnd), client_id);
|
||||
mg_random_str(client_id, sizeof(client_id) - 1);
|
||||
client_id[sizeof(client_id) - 1] = '\0';
|
||||
cid = mg_str(client_id);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
|
||||
|
||||
static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
|
||||
uint32_t localhost = mg_htonl(0x7f000001);
|
||||
if (mg_vcasecmp(&str, "localhost") != 0) return false;
|
||||
if (mg_strcasecmp(str, mg_str("localhost")) != 0) return false;
|
||||
memcpy(addr->ip, &localhost, sizeof(uint32_t));
|
||||
addr->is_ip6 = false;
|
||||
return true;
|
||||
|
||||
@@ -5,7 +5,10 @@ void mg_rpc_add(struct mg_rpc **head, struct mg_str method,
|
||||
void (*fn)(struct mg_rpc_req *), void *fn_data) {
|
||||
struct mg_rpc *rpc = (struct mg_rpc *) calloc(1, sizeof(*rpc));
|
||||
if (rpc != NULL) {
|
||||
rpc->method = mg_strdup(method), rpc->fn = fn, rpc->fn_data = fn_data;
|
||||
rpc->method.buf = mg_mprintf("%.*s", method.len, method.buf);
|
||||
rpc->method.len = method.len;
|
||||
rpc->fn = fn;
|
||||
rpc->fn_data = fn_data;
|
||||
rpc->next = *head, *head = rpc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,57 +10,24 @@ struct mg_str mg_str_n(const char *s, size_t n) {
|
||||
return str;
|
||||
}
|
||||
|
||||
int mg_lower(const char *s) {
|
||||
int c = *s;
|
||||
if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
|
||||
return c;
|
||||
}
|
||||
|
||||
int mg_ncasecmp(const char *s1, const char *s2, size_t len) {
|
||||
int diff = 0;
|
||||
if (len > 0) do {
|
||||
diff = mg_lower(s1++) - mg_lower(s2++);
|
||||
} while (diff == 0 && s1[-1] != '\0' && --len > 0);
|
||||
return diff;
|
||||
static char tolc(char c) {
|
||||
return (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
|
||||
}
|
||||
|
||||
int mg_casecmp(const char *s1, const char *s2) {
|
||||
return mg_ncasecmp(s1, s2, (size_t) ~0);
|
||||
}
|
||||
|
||||
int mg_vcmp(const struct mg_str *s1, const char *s2) {
|
||||
size_t n2 = strlen(s2), n1 = s1->len;
|
||||
int r = strncmp(s1->buf, s2, (n1 < n2) ? n1 : n2);
|
||||
if (r == 0) return (int) (n1 - n2);
|
||||
return r;
|
||||
}
|
||||
|
||||
int mg_vcasecmp(const struct mg_str *str1, const char *str2) {
|
||||
size_t n2 = strlen(str2), n1 = str1->len;
|
||||
int r = mg_ncasecmp(str1->buf, str2, (n1 < n2) ? n1 : n2);
|
||||
if (r == 0) return (int) (n1 - n2);
|
||||
return r;
|
||||
}
|
||||
|
||||
struct mg_str mg_strdup(const struct mg_str s) {
|
||||
struct mg_str r = {NULL, 0};
|
||||
if (s.len > 0 && s.buf != NULL) {
|
||||
char *sc = (char *) calloc(1, s.len + 1);
|
||||
if (sc != NULL) {
|
||||
memcpy(sc, s.buf, s.len);
|
||||
sc[s.len] = '\0';
|
||||
r.buf = sc;
|
||||
r.len = s.len;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
int diff = 0;
|
||||
do {
|
||||
char c = tolc(*s1++), d = tolc(*s2++);
|
||||
diff = c - d;
|
||||
} while (diff == 0 && s1[-1] != '\0');
|
||||
return diff;
|
||||
}
|
||||
|
||||
int mg_strcmp(const struct mg_str str1, const struct mg_str str2) {
|
||||
size_t i = 0;
|
||||
while (i < str1.len && i < str2.len) {
|
||||
int c1 = str1.buf[i];
|
||||
int c2 = str2.buf[i];
|
||||
char c1 = str1.buf[i];
|
||||
char c2 = str2.buf[i];
|
||||
if (c1 < c2) return -1;
|
||||
if (c1 > c2) return 1;
|
||||
i++;
|
||||
@@ -70,27 +37,18 @@ int mg_strcmp(const struct mg_str str1, const struct mg_str str2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *mg_strstr(const struct mg_str haystack,
|
||||
const struct mg_str needle) {
|
||||
size_t i;
|
||||
if (needle.len > haystack.len) return NULL;
|
||||
if (needle.len == 0) return haystack.buf;
|
||||
for (i = 0; i <= haystack.len - needle.len; i++) {
|
||||
if (memcmp(haystack.buf + i, needle.buf, needle.len) == 0) {
|
||||
return haystack.buf + i;
|
||||
}
|
||||
int mg_strcasecmp(const struct mg_str str1, const struct mg_str str2) {
|
||||
size_t i = 0;
|
||||
while (i < str1.len && i < str2.len) {
|
||||
char c1 = tolc(str1.buf[i]);
|
||||
char c2 = tolc(str2.buf[i]);
|
||||
if (c1 < c2) return -1;
|
||||
if (c1 > c2) return 1;
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool is_space(int c) {
|
||||
return c == ' ' || c == '\r' || c == '\n' || c == '\t';
|
||||
}
|
||||
|
||||
struct mg_str mg_strstrip(struct mg_str s) {
|
||||
while (s.len > 0 && is_space((int) *s.buf)) s.buf++, s.len--;
|
||||
while (s.len > 0 && is_space((int) *(s.buf + s.len - 1))) s.len--;
|
||||
return s;
|
||||
if (i < str1.len) return 1;
|
||||
if (i < str2.len) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
|
||||
@@ -125,10 +83,6 @@ bool mg_match(struct mg_str s, struct mg_str p, struct mg_str *caps) {
|
||||
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);
|
||||
}
|
||||
|
||||
bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char sep) {
|
||||
if (s.len == 0 || s.buf == NULL) {
|
||||
return false; // Empty string, nothing to span - fail
|
||||
@@ -142,27 +96,17 @@ bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char sep) {
|
||||
}
|
||||
}
|
||||
|
||||
char *mg_hex(const void *buf, size_t len, char *to) {
|
||||
const unsigned char *p = (const unsigned char *) buf;
|
||||
const char *hex = "0123456789abcdef";
|
||||
size_t i = 0;
|
||||
for (; len--; p++) {
|
||||
to[i++] = hex[p[0] >> 4];
|
||||
to[i++] = hex[p[0] & 0x0f];
|
||||
}
|
||||
to[i] = '\0';
|
||||
return to;
|
||||
}
|
||||
|
||||
static unsigned char mg_unhex_nimble(unsigned char c) {
|
||||
return (c >= '0' && c <= '9') ? (unsigned char) (c - '0')
|
||||
: (c >= 'A' && c <= 'F') ? (unsigned char) (c - '7')
|
||||
: (unsigned char) (c - 'W');
|
||||
uint8_t mg_toi(char c, int base) {
|
||||
return (c >= '0' && c <= '9') ? (uint8_t) (c - '0')
|
||||
: base == 16 ? (c >= 'A' && c <= 'F') ? (uint8_t) (c - '7')
|
||||
: (c >= 'a' && c <= 'f') ? (uint8_t) (c - 'W')
|
||||
: (uint8_t) ~0
|
||||
: (uint8_t) ~0;
|
||||
}
|
||||
|
||||
unsigned long mg_unhexn(const char *s, size_t len) {
|
||||
unsigned long i = 0, v = 0;
|
||||
for (i = 0; i < len; i++) v <<= 4, v |= mg_unhex_nimble(((uint8_t *) s)[i]);
|
||||
for (i = 0; i < len; i++) v <<= 4, v |= mg_toi(((char *) s)[i], 16);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -172,15 +116,3 @@ void mg_unhex(const char *buf, size_t len, unsigned char *to) {
|
||||
to[i >> 1] = (unsigned char) mg_unhexn(&buf[i], 2);
|
||||
}
|
||||
}
|
||||
|
||||
bool mg_path_is_sane(const struct mg_str path) {
|
||||
const char *s = path.buf;
|
||||
size_t n = path.len;
|
||||
if (path.buf[0] == '.' && path.buf[1] == '.') return false; // Starts with ..
|
||||
for (; s[0] != '\0' && n > 0; s++, n--) {
|
||||
if ((s[0] == '/' || s[0] == '\\') && n >= 2) { // Subdir?
|
||||
if (s[1] == '.' && s[2] == '.') return false; // Starts with ..
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -13,19 +13,13 @@ struct mg_str {
|
||||
|
||||
struct mg_str mg_str(const char *s);
|
||||
struct mg_str mg_str_n(const char *s, size_t n);
|
||||
int mg_lower(const char *s);
|
||||
int mg_ncasecmp(const char *s1, const char *s2, size_t len);
|
||||
int mg_casecmp(const char *s1, const char *s2);
|
||||
int mg_vcmp(const struct mg_str *s1, const char *s2);
|
||||
int mg_vcasecmp(const struct mg_str *str1, const char *str2);
|
||||
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);
|
||||
int mg_strcasecmp(const struct mg_str str1, const struct mg_str str2); // this one is new
|
||||
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_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char delim);
|
||||
char *mg_hex(const void *buf, size_t len, char *dst);
|
||||
|
||||
void mg_unhex(const char *buf, size_t len, unsigned char *to);
|
||||
unsigned long mg_unhexn(const char *s, size_t len);
|
||||
bool mg_path_is_sane(const struct mg_str path);
|
||||
|
||||
uint8_t mg_toi(char c, int base); // base: 16, 10
|
||||
+2
-1
@@ -1233,7 +1233,8 @@ static int mg_parse_pem(const struct mg_str pem, const struct mg_str label,
|
||||
const char *c;
|
||||
struct mg_str caps[5];
|
||||
if (!mg_match(pem, mg_str("#-----BEGIN #-----#-----END #-----#"), caps)) {
|
||||
*der = mg_strdup(pem);
|
||||
der->buf = mg_mprintf("%.*s", pem.len, pem.buf);
|
||||
der->len = pem.len;
|
||||
return 0;
|
||||
}
|
||||
if (mg_strcmp(caps[1], label) != 0 || mg_strcmp(caps[3], label) != 0) {
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) {
|
||||
}
|
||||
mbedtls_ssl_conf_rng(&tls->conf, mg_mbed_rng, c);
|
||||
|
||||
if (opts->ca.len == 0 || mg_vcmp(&opts->ca, "*") == 0) {
|
||||
if (opts->ca.len == 0 || mg_strcmp(opts->ca, mg_str("*")) == 0) {
|
||||
mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE);
|
||||
} else {
|
||||
if (mg_load_cert(opts->ca, &tls->ca) == false) goto fail;
|
||||
|
||||
+12
@@ -106,6 +106,18 @@ int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) {
|
||||
return allowed == '+';
|
||||
}
|
||||
|
||||
bool mg_path_is_sane(const struct mg_str path) {
|
||||
const char *s = path.buf;
|
||||
size_t n = path.len;
|
||||
if (path.buf[0] == '.' && path.buf[1] == '.') return false; // Starts with ..
|
||||
for (; s[0] != '\0' && n > 0; s++, n--) {
|
||||
if ((s[0] == '/' || s[0] == '\\') && n >= 2) { // Subdir?
|
||||
if (s[1] == '.' && s[2] == '.') return false; // Starts with ..
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if MG_ENABLE_CUSTOM_MILLIS
|
||||
#else
|
||||
uint64_t mg_millis(void) {
|
||||
|
||||
@@ -19,6 +19,7 @@ uint32_t mg_ntohl(uint32_t net);
|
||||
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
|
||||
uint64_t mg_millis(void); // Return milliseconds since boot
|
||||
uint64_t mg_now(void); // Return milliseconds since Epoch
|
||||
bool mg_path_is_sane(const struct mg_str path);
|
||||
|
||||
#define mg_htons(x) mg_ntohs(x)
|
||||
#define mg_htonl(x) mg_ntohl(x)
|
||||
|
||||
Reference in new issue
Block a user