mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-26 22:41:03 +08:00
mg_iobuf_delete -> mg_iobuf_del
This commit is contained in:
parent
bd64043377
commit
913e730ec2
139
docs/README.md
139
docs/README.md
@ -321,7 +321,7 @@ This example is a simple TCP echo server that listens on port 1234:
|
||||
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
if (ev == MG_EV_READ) {
|
||||
mg_send(c, c->recv.buf, c->recv.len); // Echo received data back
|
||||
mg_iobuf_delete(&c->recv, c->recv.len); // And discard it
|
||||
mg_iobuf_del(&c->recv, 0, c->recv.len); // And discard it
|
||||
}
|
||||
}
|
||||
|
||||
@ -620,14 +620,14 @@ mg_iobuf_init(&io, 0); // Empty buffer
|
||||
mg_iobuf_append(&io, "hi", 2, 1024); // io->len is 2, io->size is 1024
|
||||
```
|
||||
|
||||
### mg\_iobuf\_delete()
|
||||
### mg\_iobuf\_del()
|
||||
|
||||
```c
|
||||
size_t mg_iobuf_delete(struct mg_iobuf *io, size_t len);
|
||||
size_t mg_iobuf_del(struct mg_iobuf *io, size_t offset, size_t len);
|
||||
```
|
||||
|
||||
Discard `len` bytes from the beginning of the buffer, and shift the remaining
|
||||
bytes to the beginning. If `len` is greater than `io->len`, nothing happens,
|
||||
Delete `len` bytes starting from `offset`, and shift the remaining
|
||||
bytes. If `len` is greater than `io->len`, nothing happens,
|
||||
so such call is silently ignored.
|
||||
|
||||
|
||||
@ -1189,71 +1189,6 @@ while (mg_commalist(&s, &k, &v)) // This loop output:
|
||||
(int) k.len, k.ptr, (int) v.len, v.ptr); // [b] set to [777]
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Utility
|
||||
|
||||
|
||||
### mg\_file\_read()
|
||||
|
||||
```c
|
||||
char *mg_file_read(const char *path, size_t *sizep);
|
||||
```
|
||||
|
||||
Read file contents into a nul-terminated malloc-ed string. It is a caller's
|
||||
responsibility to free() a returned pointer. If `sizep` is not NULL, it will
|
||||
return a file size in bytes.
|
||||
|
||||
### mg\_file\_write()
|
||||
|
||||
```c
|
||||
bool mg_file_write(const char *path, const void *buf, size_t len);
|
||||
```
|
||||
|
||||
Write data to a file, return `true` if written, `false` otherwise.
|
||||
The write is atomic, i.e. data gets written to a temporary file first,
|
||||
then `rename()-ed` to a destination file name.
|
||||
|
||||
|
||||
### mg\_file\_printf()
|
||||
|
||||
```c
|
||||
int mg_file_printf(const char *path, const char *fmt, ...);
|
||||
```
|
||||
|
||||
Write into a file `path` using `printf()` semantics.
|
||||
Return `true` on success, `false` otherwise. This function prints data to
|
||||
a temporary in-memory buffer first, then calls `mg_file_write()`.
|
||||
|
||||
|
||||
### mg\_random()
|
||||
|
||||
```c
|
||||
void mg_random(void *buf, size_t len);
|
||||
```
|
||||
|
||||
Fill in buffer `buf`, `len` with random data.
|
||||
|
||||
|
||||
### mg\_ntohs()
|
||||
|
||||
```c
|
||||
uint16_t mg_ntohs(uint16_t net);
|
||||
```
|
||||
|
||||
Convert `uint16_t` value to host order.
|
||||
|
||||
|
||||
### mg\_ntohl()
|
||||
|
||||
```c
|
||||
uint32_t mg_ntohl(uint32_t net);
|
||||
```
|
||||
|
||||
Convert `uint32_t` value to host order.
|
||||
|
||||
|
||||
### mg\_hexdump()
|
||||
|
||||
```c
|
||||
@ -1343,6 +1278,70 @@ char *mg_ntoa(const struct mg_addr *, char *buf, size_t len);
|
||||
|
||||
Stringify IP address `ipaddr` into a buffer `buf`, `len`. Return `buf`.
|
||||
|
||||
|
||||
|
||||
## Utility
|
||||
|
||||
|
||||
### mg\_file\_read()
|
||||
|
||||
```c
|
||||
char *mg_file_read(const char *path, size_t *sizep);
|
||||
```
|
||||
|
||||
Read file contents into a nul-terminated malloc-ed string. It is a caller's
|
||||
responsibility to free() a returned pointer. If `sizep` is not NULL, it will
|
||||
return a file size in bytes.
|
||||
|
||||
### mg\_file\_write()
|
||||
|
||||
```c
|
||||
bool mg_file_write(const char *path, const void *buf, size_t len);
|
||||
```
|
||||
|
||||
Write data to a file, return `true` if written, `false` otherwise.
|
||||
The write is atomic, i.e. data gets written to a temporary file first,
|
||||
then `rename()-ed` to a destination file name.
|
||||
|
||||
|
||||
### mg\_file\_printf()
|
||||
|
||||
```c
|
||||
int mg_file_printf(const char *path, const char *fmt, ...);
|
||||
```
|
||||
|
||||
Write into a file `path` using `printf()` semantics.
|
||||
Return `true` on success, `false` otherwise. This function prints data to
|
||||
a temporary in-memory buffer first, then calls `mg_file_write()`.
|
||||
|
||||
|
||||
### mg\_random()
|
||||
|
||||
```c
|
||||
void mg_random(void *buf, size_t len);
|
||||
```
|
||||
|
||||
Fill in buffer `buf`, `len` with random data.
|
||||
|
||||
|
||||
### mg\_ntohs()
|
||||
|
||||
```c
|
||||
uint16_t mg_ntohs(uint16_t net);
|
||||
```
|
||||
|
||||
Convert `uint16_t` value to host order.
|
||||
|
||||
|
||||
### mg\_ntohl()
|
||||
|
||||
```c
|
||||
uint32_t mg_ntohl(uint32_t net);
|
||||
```
|
||||
|
||||
Convert `uint32_t` value to host order.
|
||||
|
||||
|
||||
### mg\_time()
|
||||
|
||||
```
|
||||
|
@ -36,7 +36,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
memcpy(buf + sizeof(*h) + n, answer, sizeof(answer)); // And answer
|
||||
mg_send(c, buf, sizeof(buf)); // And send it!
|
||||
}
|
||||
mg_iobuf_delete(&c->recv, c->recv.len);
|
||||
mg_iobuf_del(&c->recv, 0, c->recv.len);
|
||||
}
|
||||
(void) fn_data;
|
||||
(void) ev_data;
|
||||
|
@ -39,7 +39,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
connected = true;
|
||||
LOG(LL_DEBUG,
|
||||
("Connected to proxy, status: %.*s", (int) hm.uri.len, hm.uri.ptr));
|
||||
mg_iobuf_delete(&c->recv, n);
|
||||
mg_iobuf_del(&c->recv, 0, n);
|
||||
// Send request to the target server
|
||||
mg_printf(c, "GET / HTTP/1.0\r\nHost: %.*s\r\n\r\n", (int) host.len,
|
||||
host.ptr);
|
||||
|
@ -56,7 +56,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
if (c->label[0] == 'B' && c2 != NULL) {
|
||||
// All incoming data from the backend, forward to the client
|
||||
mg_send(c2, c->recv.buf, c->recv.len);
|
||||
mg_iobuf_delete(&c->recv, c->recv.len);
|
||||
mg_iobuf_del(&c->recv, 0, c->recv.len);
|
||||
}
|
||||
} else if (ev == MG_EV_CONNECT) {
|
||||
if (mg_url_is_ssl(s_backend_url)) {
|
||||
|
@ -53,7 +53,7 @@ static void handshake(struct mg_connection *c) {
|
||||
// TODO(lsm): support other auth methods
|
||||
if (r->buf[i] == HANDSHAKE_NOAUTH) reply[1] = r->buf[i];
|
||||
}
|
||||
mg_iobuf_delete(r, 2 + r->buf[1]);
|
||||
mg_iobuf_del(r, 0, 2 + r->buf[1]);
|
||||
mg_send(c, reply, sizeof(reply));
|
||||
c->label[0] = STATE_REQUEST;
|
||||
}
|
||||
@ -73,7 +73,7 @@ static void exchange(struct mg_connection *c) {
|
||||
struct mg_connection *c2 = (struct mg_connection *) c->fn_data;
|
||||
if (c2 != NULL) {
|
||||
mg_send(c2, c->recv.buf, c->recv.len);
|
||||
mg_iobuf_delete(&c->recv, c->recv.len);
|
||||
mg_iobuf_del(&c->recv, 0, c->recv.len);
|
||||
} else {
|
||||
c->is_draining = 1;
|
||||
}
|
||||
@ -145,7 +145,7 @@ static void request(struct mg_connection *c) {
|
||||
mg_send(c, buf, sizeof(buf));
|
||||
}
|
||||
mg_send(c, r->buf + 3, addr_len + 1 + 2);
|
||||
mg_iobuf_delete(r, 6 + addr_len); // Remove request from the input stream
|
||||
mg_iobuf_del(r, 0, 6 + addr_len); // Remove request from the input stream
|
||||
c->label[0] = STATE_ESTABLISHED; // Mark ourselves as connected
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
// Got websocket frame. Received data is wm->data. Echo it back!
|
||||
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
|
||||
mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT);
|
||||
mg_iobuf_delete(&c->recv, c->recv.len);
|
||||
mg_iobuf_del(&c->recv, 0, c->recv.len);
|
||||
}
|
||||
(void) fn_data;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
// Got websocket frame. Received data is wm->data. Echo it back!
|
||||
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
|
||||
mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT);
|
||||
mg_iobuf_delete(&c->recv, c->recv.len);
|
||||
mg_iobuf_del(&c->recv, 0, c->recv.len);
|
||||
}
|
||||
(void) fn_data;
|
||||
}
|
||||
|
63
mongoose.c
63
mongoose.c
@ -1686,7 +1686,7 @@ static void http_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
|
||||
break;
|
||||
} else if (n > 0 && (size_t) c->recv.len >= hm.message.len) {
|
||||
mg_call(c, MG_EV_HTTP_MSG, &hm);
|
||||
mg_iobuf_delete(&c->recv, hm.message.len);
|
||||
mg_iobuf_del(&c->recv, 0, hm.message.len);
|
||||
} else {
|
||||
if (n > 0 && !is_chunked) {
|
||||
hm.chunk =
|
||||
@ -1785,10 +1785,6 @@ size_t mg_iobuf_del(struct mg_iobuf *io, size_t ofs, size_t len) {
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t mg_iobuf_delete(struct mg_iobuf *io, size_t len) {
|
||||
return mg_iobuf_del(io, 0, len);
|
||||
}
|
||||
|
||||
void mg_iobuf_free(struct mg_iobuf *io) {
|
||||
mg_iobuf_resize(io, 0);
|
||||
}
|
||||
@ -2094,14 +2090,14 @@ enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED };
|
||||
void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags,
|
||||
uint32_t len) {
|
||||
uint8_t buf[1 + sizeof(len)], *vlen = &buf[1];
|
||||
buf[0] = (uint8_t)((cmd << 4) | flags);
|
||||
buf[0] = (uint8_t) ((cmd << 4) | flags);
|
||||
do {
|
||||
*vlen = len % 0x80;
|
||||
len /= 0x80;
|
||||
if (len > 0) *vlen |= 0x80;
|
||||
vlen++;
|
||||
} while (len > 0 && vlen < &buf[sizeof(buf)]);
|
||||
mg_send(c, buf, (size_t)(vlen - buf));
|
||||
mg_send(c, buf, (size_t) (vlen - buf));
|
||||
}
|
||||
|
||||
static void mg_send_u16(struct mg_connection *c, uint16_t value) {
|
||||
@ -2111,7 +2107,7 @@ static void mg_send_u16(struct mg_connection *c, uint16_t value) {
|
||||
void mg_mqtt_login(struct mg_connection *c, const char *url,
|
||||
struct mg_mqtt_opts *opts) {
|
||||
uint32_t total_len = 7 + 1 + 2 + 2;
|
||||
uint16_t flags = (uint16_t)(((uint16_t) opts->qos & 3) << 3);
|
||||
uint16_t flags = (uint16_t) (((uint16_t) opts->qos & 3) << 3);
|
||||
struct mg_str user = mg_url_user(url);
|
||||
struct mg_str pass = mg_url_pass(url);
|
||||
|
||||
@ -2157,7 +2153,7 @@ void mg_mqtt_login(struct mg_connection *c, const char *url,
|
||||
|
||||
void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
|
||||
struct mg_str *data, int qos, bool retain) {
|
||||
uint8_t flags = (uint8_t)(((qos & 3) << 1) | (retain ? 1 : 0));
|
||||
uint8_t flags = (uint8_t) (((qos & 3) << 1) | (retain ? 1 : 0));
|
||||
uint32_t total_len = 2 + (uint32_t) topic->len + (uint32_t) data->len;
|
||||
LOG(LL_DEBUG, ("%lu [%.*s] -> [%.*s]", c->id, (int) topic->len,
|
||||
(char *) topic->ptr, (int) data->len, (char *) data->ptr));
|
||||
@ -2193,21 +2189,21 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
|
||||
memset(m, 0, sizeof(*m));
|
||||
m->dgram.ptr = (char *) buf;
|
||||
if (len < 2) return MQTT_INCOMPLETE;
|
||||
m->cmd = (uint8_t)(buf[0] >> 4);
|
||||
m->cmd = (uint8_t) (buf[0] >> 4);
|
||||
m->qos = (buf[0] >> 1) & 3;
|
||||
|
||||
n = len_len = 0;
|
||||
p = (uint8_t *) buf + 1;
|
||||
while ((size_t)(p - buf) < len) {
|
||||
while ((size_t) (p - buf) < len) {
|
||||
lc = *((uint8_t *) p++);
|
||||
n += (uint32_t)((lc & 0x7f) << 7 * len_len);
|
||||
n += (uint32_t) ((lc & 0x7f) << 7 * len_len);
|
||||
len_len++;
|
||||
if (!(lc & 0x80)) break;
|
||||
if (len_len >= 4) return MQTT_MALFORMED;
|
||||
}
|
||||
end = p + n;
|
||||
if (lc & 0x80 || end > buf + len) return MQTT_INCOMPLETE;
|
||||
m->dgram.len = (size_t)(end - buf);
|
||||
m->dgram.len = (size_t) (end - buf);
|
||||
|
||||
switch (m->cmd) {
|
||||
case MQTT_CMD_CONNACK:
|
||||
@ -2220,28 +2216,28 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
|
||||
case MQTT_CMD_PUBCOMP:
|
||||
case MQTT_CMD_SUBACK:
|
||||
if (p + 2 > end) return MQTT_MALFORMED;
|
||||
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||
m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
|
||||
break;
|
||||
case MQTT_CMD_SUBSCRIBE: {
|
||||
if (p + 2 > end) return MQTT_MALFORMED;
|
||||
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||
m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
|
||||
p += 2;
|
||||
break;
|
||||
}
|
||||
case MQTT_CMD_PUBLISH: {
|
||||
if (p + 2 > end) return MQTT_MALFORMED;
|
||||
m->topic.len = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||
m->topic.len = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
|
||||
m->topic.ptr = (char *) p + 2;
|
||||
p += 2 + m->topic.len;
|
||||
if (p > end) return MQTT_MALFORMED;
|
||||
if (m->qos > 0) {
|
||||
if (p + 2 > end) return MQTT_MALFORMED;
|
||||
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||
m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
|
||||
p += 2;
|
||||
}
|
||||
if (p > end) return MQTT_MALFORMED;
|
||||
m->data.ptr = (char *) p;
|
||||
m->data.len = (size_t)(end - p);
|
||||
m->data.len = (size_t) (end - p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -2257,7 +2253,7 @@ static size_t mg_mqtt_next_topic(struct mg_mqtt_message *msg,
|
||||
size_t new_pos;
|
||||
if (pos >= msg->dgram.len) return 0;
|
||||
|
||||
topic->len = (size_t)(((unsigned) buf[0]) << 8 | buf[1]);
|
||||
topic->len = (size_t) (((unsigned) buf[0]) << 8 | buf[1]);
|
||||
topic->ptr = (char *) buf + 2;
|
||||
new_pos = pos + 2 + topic->len + (qos == NULL ? 0 : 1);
|
||||
if ((size_t) new_pos > msg->dgram.len) return 0;
|
||||
@ -2308,7 +2304,7 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
|
||||
}
|
||||
}
|
||||
mg_call(c, MG_EV_MQTT_CMD, &mm);
|
||||
mg_iobuf_delete(&c->recv, mm.dgram.len);
|
||||
mg_iobuf_del(&c->recv, 0, mm.dgram.len);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -2951,7 +2947,7 @@ static void mg_set_non_blocking_mode(SOCKET fd) {
|
||||
setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off));
|
||||
setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off));
|
||||
#elif MG_ARCH == MG_ARCH_FREERTOS_LWIP
|
||||
lwip_fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
lwip_fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
#else
|
||||
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK, FD_CLOEXEC);
|
||||
#endif
|
||||
@ -2969,21 +2965,22 @@ SOCKET mg_open_listener(const char *url, struct mg_addr *addr) {
|
||||
int on = 1, af = addr->is_ip6 ? AF_INET6 : AF_INET;
|
||||
int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
|
||||
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
(void)on;
|
||||
(void) on;
|
||||
|
||||
if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
|
||||
#if (!defined(_WIN32) || !defined(SO_EXCLUSIVEADDRUSE)) \
|
||||
&& (!defined(LWIP_SOCKET) || (defined(LWIP_SOCKET) && SO_REUSE == 1))
|
||||
#if (!defined(_WIN32) || !defined(SO_EXCLUSIVEADDRUSE)) && \
|
||||
(!defined(LWIP_SOCKET) || (defined(LWIP_SOCKET) && SO_REUSE == 1))
|
||||
// 1. SO_RESUSEADDR is not enabled on Windows because the semantics of
|
||||
// SO_REUSEADDR on UNIX and Windows is different. On Windows,
|
||||
// SO_REUSEADDR allows to bind a socket to a port without error even if
|
||||
// the port is already open by another program. This is not the behavior
|
||||
// SO_REUSEADDR was designed for, and leads to hard-to-track failure
|
||||
// scenarios. Therefore, SO_REUSEADDR was disabled on Windows unless
|
||||
// SO_EXCLUSIVEADDRUSE is supported and set on a socket.
|
||||
// 2. In case of LWIP, SO_REUSEADDR should be explicitly enabled, by defining
|
||||
// SO_REUSEADDR allows to bind a socket to a port without error even
|
||||
// if the port is already open by another program. This is not the
|
||||
// behavior SO_REUSEADDR was designed for, and leads to hard-to-track
|
||||
// failure scenarios. Therefore, SO_REUSEADDR was disabled on Windows
|
||||
// unless SO_EXCLUSIVEADDRUSE is supported and set on a socket.
|
||||
// 2. In case of LWIP, SO_REUSEADDR should be explicitly enabled, by
|
||||
// defining
|
||||
// SO_REUSE (in lwipopts.h), otherwise the code below will compile
|
||||
// but won't work! (setsockopt will return EINVAL)
|
||||
// but won't work! (setsockopt will return EINVAL)
|
||||
!setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) &&
|
||||
#endif
|
||||
#if defined(_WIN32) && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
|
||||
@ -3087,7 +3084,7 @@ static void write_conn(struct mg_connection *c) {
|
||||
LOG(LL_INFO, ("\n-- %lu %s %s %ld\n%s", c->id, c->label, "<-", n, s));
|
||||
free(s);
|
||||
}
|
||||
mg_iobuf_delete(&c->send, (size_t) n);
|
||||
mg_iobuf_del(&c->send, 0, (size_t) n);
|
||||
if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
|
||||
mg_call(c, MG_EV_WRITE, &n);
|
||||
// if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
|
||||
@ -4624,7 +4621,7 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data,
|
||||
c->is_websocket = 1;
|
||||
mg_call(c, MG_EV_WS_OPEN, &hm);
|
||||
}
|
||||
mg_iobuf_delete(&c->recv, (size_t) n);
|
||||
mg_iobuf_del(&c->recv, 0, (size_t) n);
|
||||
} else {
|
||||
return; // A request is not yet received
|
||||
}
|
||||
|
@ -636,7 +636,6 @@ int mg_iobuf_init(struct mg_iobuf *, size_t);
|
||||
int mg_iobuf_resize(struct mg_iobuf *, size_t);
|
||||
void mg_iobuf_free(struct mg_iobuf *);
|
||||
size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t);
|
||||
size_t mg_iobuf_delete(struct mg_iobuf *, size_t len);
|
||||
size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);
|
||||
|
||||
int mg_base64_update(unsigned char p, char *to, int len);
|
||||
|
@ -915,7 +915,7 @@ static void http_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {
|
||||
break;
|
||||
} else if (n > 0 && (size_t) c->recv.len >= hm.message.len) {
|
||||
mg_call(c, MG_EV_HTTP_MSG, &hm);
|
||||
mg_iobuf_delete(&c->recv, hm.message.len);
|
||||
mg_iobuf_del(&c->recv, 0, hm.message.len);
|
||||
} else {
|
||||
if (n > 0 && !is_chunked) {
|
||||
hm.chunk =
|
||||
|
@ -65,10 +65,6 @@ size_t mg_iobuf_del(struct mg_iobuf *io, size_t ofs, size_t len) {
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t mg_iobuf_delete(struct mg_iobuf *io, size_t len) {
|
||||
return mg_iobuf_del(io, 0, len);
|
||||
}
|
||||
|
||||
void mg_iobuf_free(struct mg_iobuf *io) {
|
||||
mg_iobuf_resize(io, 0);
|
||||
}
|
||||
|
@ -11,5 +11,4 @@ int mg_iobuf_init(struct mg_iobuf *, size_t);
|
||||
int mg_iobuf_resize(struct mg_iobuf *, size_t);
|
||||
void mg_iobuf_free(struct mg_iobuf *);
|
||||
size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t);
|
||||
size_t mg_iobuf_delete(struct mg_iobuf *, size_t len);
|
||||
size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);
|
||||
|
30
src/mqtt.c
30
src/mqtt.c
@ -20,14 +20,14 @@ enum { MQTT_OK, MQTT_INCOMPLETE, MQTT_MALFORMED };
|
||||
void mg_mqtt_send_header(struct mg_connection *c, uint8_t cmd, uint8_t flags,
|
||||
uint32_t len) {
|
||||
uint8_t buf[1 + sizeof(len)], *vlen = &buf[1];
|
||||
buf[0] = (uint8_t)((cmd << 4) | flags);
|
||||
buf[0] = (uint8_t) ((cmd << 4) | flags);
|
||||
do {
|
||||
*vlen = len % 0x80;
|
||||
len /= 0x80;
|
||||
if (len > 0) *vlen |= 0x80;
|
||||
vlen++;
|
||||
} while (len > 0 && vlen < &buf[sizeof(buf)]);
|
||||
mg_send(c, buf, (size_t)(vlen - buf));
|
||||
mg_send(c, buf, (size_t) (vlen - buf));
|
||||
}
|
||||
|
||||
static void mg_send_u16(struct mg_connection *c, uint16_t value) {
|
||||
@ -37,7 +37,7 @@ static void mg_send_u16(struct mg_connection *c, uint16_t value) {
|
||||
void mg_mqtt_login(struct mg_connection *c, const char *url,
|
||||
struct mg_mqtt_opts *opts) {
|
||||
uint32_t total_len = 7 + 1 + 2 + 2;
|
||||
uint16_t flags = (uint16_t)(((uint16_t) opts->qos & 3) << 3);
|
||||
uint16_t flags = (uint16_t) (((uint16_t) opts->qos & 3) << 3);
|
||||
struct mg_str user = mg_url_user(url);
|
||||
struct mg_str pass = mg_url_pass(url);
|
||||
|
||||
@ -83,7 +83,7 @@ void mg_mqtt_login(struct mg_connection *c, const char *url,
|
||||
|
||||
void mg_mqtt_pub(struct mg_connection *c, struct mg_str *topic,
|
||||
struct mg_str *data, int qos, bool retain) {
|
||||
uint8_t flags = (uint8_t)(((qos & 3) << 1) | (retain ? 1 : 0));
|
||||
uint8_t flags = (uint8_t) (((qos & 3) << 1) | (retain ? 1 : 0));
|
||||
uint32_t total_len = 2 + (uint32_t) topic->len + (uint32_t) data->len;
|
||||
LOG(LL_DEBUG, ("%lu [%.*s] -> [%.*s]", c->id, (int) topic->len,
|
||||
(char *) topic->ptr, (int) data->len, (char *) data->ptr));
|
||||
@ -119,21 +119,21 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
|
||||
memset(m, 0, sizeof(*m));
|
||||
m->dgram.ptr = (char *) buf;
|
||||
if (len < 2) return MQTT_INCOMPLETE;
|
||||
m->cmd = (uint8_t)(buf[0] >> 4);
|
||||
m->cmd = (uint8_t) (buf[0] >> 4);
|
||||
m->qos = (buf[0] >> 1) & 3;
|
||||
|
||||
n = len_len = 0;
|
||||
p = (uint8_t *) buf + 1;
|
||||
while ((size_t)(p - buf) < len) {
|
||||
while ((size_t) (p - buf) < len) {
|
||||
lc = *((uint8_t *) p++);
|
||||
n += (uint32_t)((lc & 0x7f) << 7 * len_len);
|
||||
n += (uint32_t) ((lc & 0x7f) << 7 * len_len);
|
||||
len_len++;
|
||||
if (!(lc & 0x80)) break;
|
||||
if (len_len >= 4) return MQTT_MALFORMED;
|
||||
}
|
||||
end = p + n;
|
||||
if (lc & 0x80 || end > buf + len) return MQTT_INCOMPLETE;
|
||||
m->dgram.len = (size_t)(end - buf);
|
||||
m->dgram.len = (size_t) (end - buf);
|
||||
|
||||
switch (m->cmd) {
|
||||
case MQTT_CMD_CONNACK:
|
||||
@ -146,28 +146,28 @@ int mg_mqtt_parse(const uint8_t *buf, size_t len, struct mg_mqtt_message *m) {
|
||||
case MQTT_CMD_PUBCOMP:
|
||||
case MQTT_CMD_SUBACK:
|
||||
if (p + 2 > end) return MQTT_MALFORMED;
|
||||
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||
m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
|
||||
break;
|
||||
case MQTT_CMD_SUBSCRIBE: {
|
||||
if (p + 2 > end) return MQTT_MALFORMED;
|
||||
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||
m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
|
||||
p += 2;
|
||||
break;
|
||||
}
|
||||
case MQTT_CMD_PUBLISH: {
|
||||
if (p + 2 > end) return MQTT_MALFORMED;
|
||||
m->topic.len = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||
m->topic.len = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
|
||||
m->topic.ptr = (char *) p + 2;
|
||||
p += 2 + m->topic.len;
|
||||
if (p > end) return MQTT_MALFORMED;
|
||||
if (m->qos > 0) {
|
||||
if (p + 2 > end) return MQTT_MALFORMED;
|
||||
m->id = (uint16_t)((((uint16_t) p[0]) << 8) | p[1]);
|
||||
m->id = (uint16_t) ((((uint16_t) p[0]) << 8) | p[1]);
|
||||
p += 2;
|
||||
}
|
||||
if (p > end) return MQTT_MALFORMED;
|
||||
m->data.ptr = (char *) p;
|
||||
m->data.len = (size_t)(end - p);
|
||||
m->data.len = (size_t) (end - p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -183,7 +183,7 @@ static size_t mg_mqtt_next_topic(struct mg_mqtt_message *msg,
|
||||
size_t new_pos;
|
||||
if (pos >= msg->dgram.len) return 0;
|
||||
|
||||
topic->len = (size_t)(((unsigned) buf[0]) << 8 | buf[1]);
|
||||
topic->len = (size_t) (((unsigned) buf[0]) << 8 | buf[1]);
|
||||
topic->ptr = (char *) buf + 2;
|
||||
new_pos = pos + 2 + topic->len + (qos == NULL ? 0 : 1);
|
||||
if ((size_t) new_pos > msg->dgram.len) return 0;
|
||||
@ -234,7 +234,7 @@ static void mqtt_cb(struct mg_connection *c, int ev, void *ev_data,
|
||||
}
|
||||
}
|
||||
mg_call(c, MG_EV_MQTT_CMD, &mm);
|
||||
mg_iobuf_delete(&c->recv, mm.dgram.len);
|
||||
mg_iobuf_del(&c->recv, 0, mm.dgram.len);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
25
src/sock.c
25
src/sock.c
@ -119,7 +119,7 @@ static void mg_set_non_blocking_mode(SOCKET fd) {
|
||||
setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off));
|
||||
setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off));
|
||||
#elif MG_ARCH == MG_ARCH_FREERTOS_LWIP
|
||||
lwip_fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
lwip_fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
#else
|
||||
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK, FD_CLOEXEC);
|
||||
#endif
|
||||
@ -137,21 +137,22 @@ SOCKET mg_open_listener(const char *url, struct mg_addr *addr) {
|
||||
int on = 1, af = addr->is_ip6 ? AF_INET6 : AF_INET;
|
||||
int type = strncmp(url, "udp:", 4) == 0 ? SOCK_DGRAM : SOCK_STREAM;
|
||||
int proto = type == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
|
||||
(void)on;
|
||||
(void) on;
|
||||
|
||||
if ((fd = socket(af, type, proto)) != INVALID_SOCKET &&
|
||||
#if (!defined(_WIN32) || !defined(SO_EXCLUSIVEADDRUSE)) \
|
||||
&& (!defined(LWIP_SOCKET) || (defined(LWIP_SOCKET) && SO_REUSE == 1))
|
||||
#if (!defined(_WIN32) || !defined(SO_EXCLUSIVEADDRUSE)) && \
|
||||
(!defined(LWIP_SOCKET) || (defined(LWIP_SOCKET) && SO_REUSE == 1))
|
||||
// 1. SO_RESUSEADDR is not enabled on Windows because the semantics of
|
||||
// SO_REUSEADDR on UNIX and Windows is different. On Windows,
|
||||
// SO_REUSEADDR allows to bind a socket to a port without error even if
|
||||
// the port is already open by another program. This is not the behavior
|
||||
// SO_REUSEADDR was designed for, and leads to hard-to-track failure
|
||||
// scenarios. Therefore, SO_REUSEADDR was disabled on Windows unless
|
||||
// SO_EXCLUSIVEADDRUSE is supported and set on a socket.
|
||||
// 2. In case of LWIP, SO_REUSEADDR should be explicitly enabled, by defining
|
||||
// SO_REUSEADDR allows to bind a socket to a port without error even
|
||||
// if the port is already open by another program. This is not the
|
||||
// behavior SO_REUSEADDR was designed for, and leads to hard-to-track
|
||||
// failure scenarios. Therefore, SO_REUSEADDR was disabled on Windows
|
||||
// unless SO_EXCLUSIVEADDRUSE is supported and set on a socket.
|
||||
// 2. In case of LWIP, SO_REUSEADDR should be explicitly enabled, by
|
||||
// defining
|
||||
// SO_REUSE (in lwipopts.h), otherwise the code below will compile
|
||||
// but won't work! (setsockopt will return EINVAL)
|
||||
// but won't work! (setsockopt will return EINVAL)
|
||||
!setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) &&
|
||||
#endif
|
||||
#if defined(_WIN32) && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)
|
||||
@ -255,7 +256,7 @@ static void write_conn(struct mg_connection *c) {
|
||||
LOG(LL_INFO, ("\n-- %lu %s %s %ld\n%s", c->id, c->label, "<-", n, s));
|
||||
free(s);
|
||||
}
|
||||
mg_iobuf_delete(&c->send, (size_t) n);
|
||||
mg_iobuf_del(&c->send, 0, (size_t) n);
|
||||
if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
|
||||
mg_call(c, MG_EV_WRITE, &n);
|
||||
// if (c->send.len == 0) mg_iobuf_resize(&c->send, 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user