diff --git a/mongoose.c b/mongoose.c
index 5a581c596c83e88f9d690b5746c5dcc4d1c0a9ca..aba87311f33f0bdeb195f9485442c20e6bb2fa68 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -2157,7 +2157,6 @@ static void mg_destroy_conn(struct mg_connection *conn) {
 #endif
   mbuf_free(&conn->recv_mbuf);
   mbuf_free(&conn->send_mbuf);
-  mbuf_free(&conn->endpoints);
 
   memset(conn, 0, sizeof(*conn));
   MG_FREE(conn);
@@ -4191,6 +4190,8 @@ struct mg_http_proto_data {
   struct mbuf strm_state; /* Used by multi-part streaming */
 #endif
   struct mg_http_proto_data_chuncked chunk;
+  struct mbuf endpoints; /* Used by mg_register_http_endpoint */
+  mg_event_handler_t endpoint_handler;
 };
 
 static void mg_http_conn_destructor(void *proto_data);
@@ -4236,6 +4237,7 @@ static void mg_http_conn_destructor(void *proto_data) {
 #ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
   mbuf_free(&pd->strm_state);
 #endif
+  mbuf_free(&pd->endpoints);
   free(proto_data);
 }
 
@@ -4920,6 +4922,7 @@ MG_INTERNAL size_t mg_handle_chunked(struct mg_connection *nc,
 
 static mg_event_handler_t mg_http_get_endpoint_handler(
     struct mg_connection *nc, struct mg_str *uri_path) {
+  struct mg_http_proto_data *pd;
   size_t pos = 0;
   mg_event_handler_t ret = NULL;
   int matched, matched_max = 0;
@@ -4928,16 +4931,18 @@ static mg_event_handler_t mg_http_get_endpoint_handler(
     return NULL;
   }
 
-  while (pos < nc->endpoints.len) {
+  pd = mg_http_get_proto_data(nc);
+
+  while (pos < pd->endpoints.len) {
     size_t name_len;
-    memcpy(&name_len, nc->endpoints.buf + pos, sizeof(name_len));
-    if ((matched = mg_match_prefix_n(nc->endpoints.buf + pos + sizeof(size_t),
+    memcpy(&name_len, pd->endpoints.buf + pos, sizeof(name_len));
+    if ((matched = mg_match_prefix_n(pd->endpoints.buf + pos + sizeof(size_t),
                                      name_len, uri_path->p, uri_path->len)) !=
         -1) {
       if (matched > matched_max) {
         /* Looking for the longest suitable handler */
         memcpy(&ret,
-               nc->endpoints.buf + pos + sizeof(name_len) + (name_len + 1),
+               pd->endpoints.buf + pos + sizeof(name_len) + (name_len + 1),
                sizeof(ret));
         matched_max = matched;
       }
@@ -5005,11 +5010,16 @@ static void mg_http_store_stream_info(struct mbuf *buf,
 
 static void mg_http_call_endpoint_handler(struct mg_connection *nc, int ev,
                                           struct http_message *hm) {
-  mg_event_handler_t uri_handler =
-      ev == MG_EV_HTTP_REQUEST
-          ? mg_http_get_endpoint_handler(nc->listener, &hm->uri)
-          : NULL;
-  mg_call(nc, uri_handler ? uri_handler : nc->handler, ev, hm);
+  struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);
+
+  if (pd->endpoint_handler == NULL || ev == MG_EV_HTTP_REQUEST) {
+    pd->endpoint_handler =
+        ev == MG_EV_HTTP_REQUEST
+            ? mg_http_get_endpoint_handler(nc->listener, &hm->uri)
+            : NULL;
+  }
+  mg_call(nc, pd->endpoint_handler ? pd->endpoint_handler : nc->handler, ev,
+          hm);
 }
 
 #ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
@@ -5051,11 +5061,30 @@ void mg_http_handler(struct mg_connection *nc, int ev, void *ev_data) {
   struct mg_str *vec;
 #endif
   if (ev == MG_EV_CLOSE) {
-    /*
-     * For HTTP messages without Content-Length, always send HTTP message
-     * before MG_EV_CLOSE message.
-     */
-    if (io->len > 0 && mg_parse_http(io->buf, io->len, hm, is_req) > 0) {
+#ifdef MG_ENABLE_HTTP_STREAMING_MULTIPART
+    if (pd->strm_state.len != 0) {
+      /*
+       * Multipart message is in progress, but we get close
+       * MG_EV_HTTP_PART_END with error flag
+       */
+      struct mg_http_stream_info si;
+      struct mg_http_multipart_part mp;
+      memset(&mp, 0, sizeof(mp));
+
+      mg_http_parse_stream_info(&pd->strm_state, &si);
+
+      mp.status = -1;
+      mp.var_name = si.var_name.p;
+      mp.file_name = si.file_name.p;
+      mg_call(nc, pd->endpoint_handler ? pd->endpoint_handler : nc->handler,
+              MG_EV_HTTP_PART_END, &mp);
+    } else
+#endif
+        if (io->len > 0 && mg_parse_http(io->buf, io->len, hm, is_req) > 0) {
+      /*
+      * For HTTP messages without Content-Length, always send HTTP message
+      * before MG_EV_CLOSE message.
+      */
       int ev2 = is_req ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY;
       hm->message.len = io->len;
       hm->body.len = io->buf + io->len - hm->body.p;
@@ -7554,10 +7583,11 @@ size_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,
 
 void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
                                mg_event_handler_t handler) {
+  struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);
   size_t len = strlen(uri_path);
-  mbuf_append(&nc->endpoints, &len, sizeof(len));
-  mbuf_append(&nc->endpoints, uri_path, len + 1);
-  mbuf_append(&nc->endpoints, &handler, sizeof(handler));
+  mbuf_append(&pd->endpoints, &len, sizeof(len));
+  mbuf_append(&pd->endpoints, uri_path, len + 1);
+  mbuf_append(&pd->endpoints, &handler, sizeof(handler));
 }
 
 #endif /* MG_DISABLE_HTTP */
diff --git a/mongoose.h b/mongoose.h
index 22553c16f14fd7bc7dc01e1be23060e6798888e8..ec8031214422631439f8c0d35c6f81f31fbdab8a 100644
--- a/mongoose.h
+++ b/mongoose.h
@@ -1085,10 +1085,9 @@ struct mg_connection {
      * void pointers, since some archs might have fat pointers for functions.
      */
     mg_event_handler_t f;
-  } priv_1;              /* Used by mg_enable_multithreading() */
-  void *priv_2;          /* Used by mg_enable_multithreading() */
-  struct mbuf endpoints; /* Used by mg_register_http_endpoint */
-  void *mgr_data;        /* Implementation-specific event manager's data. */
+  } priv_1;       /* Used by mg_enable_multithreading() */
+  void *priv_2;   /* Used by mg_enable_multithreading() */
+  void *mgr_data; /* Implementation-specific event manager's data. */
   unsigned long flags;
 /* Flags set by Mongoose */
 #define MG_F_LISTENING (1 << 0)          /* This connection is listening */
@@ -1918,6 +1917,7 @@ struct mg_http_multipart_part {
   const char *file_name;
   const char *var_name;
   struct mg_str data;
+  int status; /* <0 on error */
 };
 
 /* HTTP and websocket events. void *ev_data is described in a comment. */