diff --git a/mongoose.c b/mongoose.c index 6dea122c..1f13be9f 100644 --- a/mongoose.c +++ b/mongoose.c @@ -568,7 +568,7 @@ int mg_http_parse(const char *s, size_t len, struct mg_http_message *hm) { mg_http_parse_headers(s, end, hm->headers, sizeof(hm->headers) / sizeof(hm->headers[0])); if ((cl = mg_http_get_header(hm, "Content-Length")) != NULL) { - hm->body.len = (size_t) mg_to64(cl->ptr); + hm->body.len = (size_t) mg_to64(*cl); hm->message.len = req_len + hm->body.len; } @@ -3751,14 +3751,15 @@ int mg_asprintf(char **buf, size_t size, const char *fmt, ...) { return ret; } -int64_t mg_to64(const char *s) { +int64_t mg_to64(struct mg_str str) { int64_t result = 0, neg = 1; - while (*s && isspace((unsigned char) *s)) s++; - if (*s == '-') neg = -1, s++; - while (isdigit((unsigned char) *s)) { + size_t i = 0; + while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++; + if (i < str.len && str.ptr[i] == '-') neg = -1, i++; + while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') { result *= 10; - result += (*s - '0'); - s++; + result += (str.ptr[i] - '0'); + i++; } return result * neg; } @@ -3947,24 +3948,23 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data, while (ws_process(c->recv.buf, c->recv.len, &msg) > 0) { char *s = (char *) c->recv.buf + msg.header_len; + struct mg_ws_message m = {{s, msg.data_len}, msg.flags}; switch (msg.flags & WEBSOCKET_FLAGS_MASK_OP) { case WEBSOCKET_OP_PING: LOG(LL_DEBUG, ("%s", "WS PONG")); mg_ws_send(c, s, msg.data_len, WEBSOCKET_OP_PONG); + mg_call(c, MG_EV_WS_CTL, &m); break; case WEBSOCKET_OP_PONG: - // Ignore + mg_call(c, MG_EV_WS_CTL, &m); break; - case WEBSOCKET_OP_CLOSE: { - struct mg_ws_message evd = {{s, msg.data_len}, msg.flags}; + case WEBSOCKET_OP_CLOSE: LOG(LL_ERROR, ("%lu Got WS CLOSE", c->id)); - mg_call(c, MG_EV_WS_MSG, &evd); + mg_call(c, MG_EV_WS_CTL, &m); c->is_closing = 1; return; - } default: { - struct mg_ws_message evd = {{s, msg.data_len}, msg.flags}; - mg_call(c, MG_EV_WS_MSG, &evd); + mg_call(c, MG_EV_WS_MSG, &m); break; } } diff --git a/mongoose.h b/mongoose.h index 1ec901d6..fbf7f412 100644 --- a/mongoose.h +++ b/mongoose.h @@ -428,7 +428,7 @@ void mg_unhex(const char *buf, int len, unsigned char *to); unsigned long mg_unhexn(const char *s, int len); int mg_asprintf(char **buf, size_t size, const char *fmt, ...); int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap); -int64_t mg_to64(const char *s); +int64_t mg_to64(struct mg_str str); double mg_time(void); unsigned long mg_millis(void); void mg_usleep(unsigned long usecs); @@ -570,6 +570,7 @@ enum { MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message * MG_EV_WS_OPEN, // Websocket handshake done NULL MG_EV_WS_MSG, // Websocket message received struct mg_ws_message * + MG_EV_WS_CTL, // Websocket control message struct mg_ws_message * MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message * MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message * MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code diff --git a/src/event.h b/src/event.h index 0d6de560..df8caa7a 100644 --- a/src/event.h +++ b/src/event.h @@ -29,6 +29,7 @@ enum { MG_EV_HTTP_MSG, // HTTP request/response struct mg_http_message * MG_EV_WS_OPEN, // Websocket handshake done NULL MG_EV_WS_MSG, // Websocket message received struct mg_ws_message * + MG_EV_WS_CTL, // Websocket control message struct mg_ws_message * MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message * MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message * MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code diff --git a/src/http.c b/src/http.c index 89621879..7f608836 100644 --- a/src/http.c +++ b/src/http.c @@ -169,7 +169,7 @@ int mg_http_parse(const char *s, size_t len, struct mg_http_message *hm) { mg_http_parse_headers(s, end, hm->headers, sizeof(hm->headers) / sizeof(hm->headers[0])); if ((cl = mg_http_get_header(hm, "Content-Length")) != NULL) { - hm->body.len = (size_t) mg_to64(cl->ptr); + hm->body.len = (size_t) mg_to64(*cl); hm->message.len = req_len + hm->body.len; } diff --git a/src/util.c b/src/util.c index 454782f2..dd156514 100644 --- a/src/util.c +++ b/src/util.c @@ -215,14 +215,15 @@ int mg_asprintf(char **buf, size_t size, const char *fmt, ...) { return ret; } -int64_t mg_to64(const char *s) { +int64_t mg_to64(struct mg_str str) { int64_t result = 0, neg = 1; - while (*s && isspace((unsigned char) *s)) s++; - if (*s == '-') neg = -1, s++; - while (isdigit((unsigned char) *s)) { + size_t i = 0; + while (i < str.len && (str.ptr[i] == ' ' || str.ptr[i] == '\t')) i++; + if (i < str.len && str.ptr[i] == '-') neg = -1, i++; + while (i < str.len && str.ptr[i] >= '0' && str.ptr[i] <= '9') { result *= 10; - result += (*s - '0'); - s++; + result += (str.ptr[i] - '0'); + i++; } return result * neg; } diff --git a/src/util.h b/src/util.h index 3e62a15d..77a48b2b 100644 --- a/src/util.h +++ b/src/util.h @@ -17,7 +17,7 @@ void mg_unhex(const char *buf, int len, unsigned char *to); unsigned long mg_unhexn(const char *s, int len); int mg_asprintf(char **buf, size_t size, const char *fmt, ...); int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap); -int64_t mg_to64(const char *s); +int64_t mg_to64(struct mg_str str); double mg_time(void); unsigned long mg_millis(void); void mg_usleep(unsigned long usecs); diff --git a/src/ws.c b/src/ws.c index d6abbae7..6366614c 100644 --- a/src/ws.c +++ b/src/ws.c @@ -128,24 +128,23 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data, while (ws_process(c->recv.buf, c->recv.len, &msg) > 0) { char *s = (char *) c->recv.buf + msg.header_len; + struct mg_ws_message m = {{s, msg.data_len}, msg.flags}; switch (msg.flags & WEBSOCKET_FLAGS_MASK_OP) { case WEBSOCKET_OP_PING: LOG(LL_DEBUG, ("%s", "WS PONG")); mg_ws_send(c, s, msg.data_len, WEBSOCKET_OP_PONG); + mg_call(c, MG_EV_WS_CTL, &m); break; case WEBSOCKET_OP_PONG: - // Ignore + mg_call(c, MG_EV_WS_CTL, &m); break; - case WEBSOCKET_OP_CLOSE: { - struct mg_ws_message evd = {{s, msg.data_len}, msg.flags}; + case WEBSOCKET_OP_CLOSE: LOG(LL_ERROR, ("%lu Got WS CLOSE", c->id)); - mg_call(c, MG_EV_WS_MSG, &evd); + mg_call(c, MG_EV_WS_CTL, &m); c->is_closing = 1; return; - } default: { - struct mg_ws_message evd = {{s, msg.data_len}, msg.flags}; - mg_call(c, MG_EV_WS_MSG, &evd); + mg_call(c, MG_EV_WS_MSG, &m); break; } }