Quellcode durchsuchen

1.合并mongoose高配版本,修复ws内存泄漏问题

liyuezong vor 1 Jahr
Ursprung
Commit
207d502b6e
4 geänderte Dateien mit 165 neuen und 24 gelöschten Zeilen
  1. 152 17
      ip/mongoose/mongoose.c
  2. 5 2
      ip/mongoose/mongoose.h
  3. 3 2
      ip/src/app.c
  4. 5 3
      ip/src/websocket_handle.c

+ 152 - 17
ip/mongoose/mongoose.c

@@ -1833,6 +1833,31 @@ struct packed_file {
 };
 
 #if MG_ENABLE_PACKED_FS
+static const struct packed_file2 {
+  const char *name;
+  const unsigned char *data;
+  size_t size;
+  time_t mtime;
+} packed_files[] = {
+  {NULL, NULL, 0, 0}
+};
+static int scmp(const char *a, const char *b) {
+  while (*a && (*a == *b)) a++, b++;
+  return *(const unsigned char *) a - *(const unsigned char *) b;
+}
+const char *mg_unlist(size_t no) {
+  return packed_files[no].name;
+}
+const char *mg_unpack(const char *name, size_t *size, time_t *mtime) {
+  const struct packed_file2 *p;
+  for (p = packed_files; p->name != NULL; p++) {
+    if (scmp(p->name, name) != 0) continue;
+    if (size != NULL) *size = p->size - 1;
+    if (mtime != NULL) *mtime = p->mtime;
+    return (const char *) p->data;
+  }
+  return NULL;
+}
 #else
 const char *mg_unpack(const char *path, size_t *size, time_t *mtime) {
   *size = 0, *mtime = 0;
@@ -2667,7 +2692,7 @@ int mg_http_reply2(struct mg_connection *c, int code, const char *headers,
     int r;
     if (c==NULL) return -1;
 
-    mg_printf(c, "HTTP/1.1 %d %s\r\n"
+    /*mg_printf(c, "HTTP/1.1 %d %s\r\n"
     "Content-Type: text/html\n"
     "Content-Length: %d\n"
     "Connection: Keep-Alive\n"
@@ -2677,7 +2702,18 @@ int mg_http_reply2(struct mg_connection *c, int code, const char *headers,
     "X-Xss-Protection: 1: mode=block\n"
     "Accept-Ranges: bytes\n"
     "Vary: Accept-Encoding\n\n"
-    "%s\n", code, mg_http_status_code_str(code),strlen(fmt == NULL ? "" : fmt), fmt == NULL ? "" : fmt);
+    "%s\n", code, mg_http_status_code_str(code),strlen(fmt == NULL ? "" : fmt), fmt == NULL ? "" : fmt);*/
+
+    mg_printf(c, "HTTP/1.1 %d %s\r\n"
+    "Content-Type: text/html\n"
+    "Content-Length: %d\n"
+    "Connection: Keep-Alive\n"
+    "Keep-Alive: timeout=30, max=396\n" 
+    "X-Content-Type-0ptions: nosniff\n"
+    "X-Frame-0ptions:: SAMEORIGIN\n"
+    "X-Xss-Protection: 1: mode=block\n"
+    "Accept-Ranges: bytes\n"
+    "Vary: Accept-Encoding\n\n", code, mg_http_status_code_str(code),strlen(fmt == NULL ? "" : fmt));
 
     len = c->send.len;
     va_start(ap, fmt);
@@ -2892,6 +2928,110 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm,
   }
 }
 
+
+static char *get_fname(const char *path)
+{
+    char *p=strrchr(path, '/');
+    if(p) {
+        return p+1;
+    }
+    return (char*)path;
+}
+void mg_http_serve_file2(struct mg_connection *c, struct mg_http_message *hm,
+                        const char *path,
+                        const struct mg_http_serve_opts *opts) {
+  char etag[64], tmp[MG_PATH_MAX];
+  struct mg_fs *fs = opts->fs == NULL ? &mg_fs_posix : opts->fs;
+  struct mg_fd *fd = NULL;
+  size_t size = 0;
+  time_t mtime = 0;
+  struct mg_str *inm = NULL;
+  struct mg_str mime = guess_content_type(mg_str(path), opts->mime_types);
+  bool gzip = false;
+
+  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) {
+      char *ae_ = mg_mprintf("%.*s", ae->len, ae->buf);
+      if (ae_ != NULL && 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);
+  }
+
+  // Failed to open, and page404 is configured? Open it, then
+  if (fd == NULL && opts->page404 != NULL) {
+    fd = mg_fs_open(fs, opts->page404, MG_FS_READ);
+    path = opts->page404;
+    mime = guess_content_type(mg_str(path), opts->mime_types);
+  }
+
+  if (fd == NULL || fs->st(path, &size, &mtime) == 0) {
+    mg_http_reply(c, 404, opts->extra_headers, "Not found\n");
+    mg_fs_close(fd);
+    // 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_strcasecmp(*inm, mg_str(etag)) == 0) {
+    mg_fs_close(fd);
+    mg_http_reply(c, 304, opts->extra_headers, "");
+  } else {
+    int n, status = 200;
+    char range[100];
+    size_t r1 = 0, r2 = 0, cl = size;
+
+    // Handle Range header
+    struct mg_str *rh = mg_http_get_header(hm, "Range");
+    range[0] = '\0';
+    if (rh != NULL && (n = getrange(rh, &r1, &r2)) > 0) {
+      // If range is specified like "400-", set second limit to content len
+      if (n == 1) r2 = cl - 1;
+      if (r1 > r2 || r2 >= cl) {
+        status = 416;
+        cl = 0;
+        mg_snprintf(range, sizeof(range), "Content-Range: bytes */%lld\r\n",
+                    (int64_t) size);
+      } else {
+        status = 206;
+        cl = r2 - r1 + 1;
+        mg_snprintf(range, sizeof(range),
+                    "Content-Range: bytes %llu-%llu/%llu\r\n", (uint64_t) r1,
+                    (uint64_t) (r1 + cl - 1), (uint64_t) size);
+        fs->sk(fd->fd, r1);
+      }
+    }
+    mg_printf(c,
+              "HTTP/1.1 %d %s\r\n"
+              "Content-Type: %.*s\r\n"
+              "Content-Disposition: attachment;filename=%s\r\n"
+              "Etag: %s\r\n"
+              "Content-Length: %llu\r\n"
+              "%s%s%s\r\n",
+              status, mg_http_status_code_str(status), (int) mime.len, mime.buf,
+              get_fname(path),
+              etag, (uint64_t) cl, gzip ? "Content-Encoding: gzip\r\n" : "",
+              range, opts->extra_headers ? opts->extra_headers : "");
+    if (mg_strcasecmp(hm->method, mg_str("HEAD")) == 0) {
+      c->is_draining = 1;
+      c->is_resp = 0;
+      mg_fs_close(fd);
+    } else {
+      // Track to-be-sent content length at the end of c->data, aligned
+      size_t *clp = (size_t *) &c->data[(sizeof(c->data) - sizeof(size_t)) /
+                                        sizeof(size_t) * sizeof(size_t)];
+      c->pfn = static_cb;
+      c->pfn_data = fd;
+      *clp = cl;
+    }
+  }
+}
+
 struct printdirentrydata {
   struct mg_connection *c;
   struct mg_http_message *hm;
@@ -15219,22 +15359,17 @@ size_t mg_ws_send(struct mg_connection *c, const void *buf, size_t len,
 }
 
 
-static void my_mask(uint8_t *data, size_t len) {
-    size_t i;
-    uint8_t *p=data, *mask=p-4;
-    for (i = 0; i < len; i++) p[i] ^= mask[i & 3];
-}
-size_t mg_ws_send2(struct mg_connection *c, const void *buf, size_t len,
-                  int op) {
-  uint8_t *p=malloc(len+100);
-  if(!p) return -1;
+size_t mg_ws_send2(struct mg_connection *c, const void *buf, size_t len, int op, int max_tlen) {
   uint8_t header[14];
-  size_t header_len = mkhdr(len, op, c->is_client, p);
-  memcpy(p+header_len, buf, len);
-  //my_mask(p+header_len, len);
-  mg_io_send(c, p, header_len+len);
-  free(p);
-  
+  if(!c) return -1;
+  if(max_tlen>0 && c->send.len>max_tlen) {
+    mg_iobuf_resize(&c->send, 0);
+  }
+  size_t header_len = mkhdr(len, op, c->is_client, header);
+  mg_send(c, header, header_len);
+  MG_VERBOSE(("WS out: %d [%.*s]", (int) len, (int) len, buf));
+  mg_send(c, buf, len);
+  mg_ws_mask(c, len);
   return header_len + len;
 }
 

+ 5 - 2
ip/mongoose/mongoose.h

@@ -736,7 +736,7 @@ struct timeval {
 #endif
 
 #ifndef MG_ENABLE_PACKED_FS
-#define MG_ENABLE_PACKED_FS 0
+#define MG_ENABLE_PACKED_FS 1
 #endif
 
 #ifndef MG_ENABLE_ASSERT
@@ -2123,6 +2123,9 @@ void mg_http_serve_dir(struct mg_connection *, struct mg_http_message *hm,
                        const struct mg_http_serve_opts *);
 void mg_http_serve_file(struct mg_connection *, struct mg_http_message *hm,
                         const char *path, const struct mg_http_serve_opts *);
+void mg_http_serve_file2(struct mg_connection *, struct mg_http_message *hm,
+                        const char *path, const struct mg_http_serve_opts *);
+
 void mg_http_reply(struct mg_connection *, int status_code, const char *headers,
                    const char *body_fmt, ...);
 int mg_http_reply2(struct mg_connection *c, int code, const char *headers,
@@ -2251,7 +2254,7 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *, const char *url,
 void mg_ws_upgrade(struct mg_connection *, struct mg_http_message *,
                    const char *fmt, ...);
 size_t mg_ws_send(struct mg_connection *, const void *buf, size_t len, int op);
-size_t mg_ws_send2(struct mg_connection *, const void *buf, size_t len, int op);
+size_t mg_ws_send2(struct mg_connection *, const void *buf, size_t len, int op, int max_tlen);
 size_t mg_ws_wrap(struct mg_connection *, size_t len, int op);
 size_t mg_ws_printf(struct mg_connection *c, int op, const char *fmt, ...);
 size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,

+ 3 - 2
ip/src/app.c

@@ -1326,7 +1326,7 @@ static void* ntp_thread(void *arg)
     NTPManager *pntp=&_globalNTPManager;
 
     #define NTP_TIMEOUT         5
-    #define NTP_INTERVAL_TIME   30
+    #define NTP_INTERVAL_TIME   300
     time1 = time(NULL);
     while (h->quit == 0)
     {
@@ -1354,7 +1354,8 @@ static void* ntp_thread(void *arg)
                         // _tm->tm_hour,_tm->tm_min,_tm->tm_sec);
                         // _tm->tm_year += 1900;
                         // _tm->tm_mon +=1;
-                        if(abs(host_time - utc_time) > 30) {
+                        if(host_time != utc_time) {
+                            //log_i("sdasdsadasdasddddddd:%d",abs(host_time - utc_time));
                             set_utctime(utc_time);
                             //set_time(_tm,pntp->tzone);
                             //set_time_zone(_tm,pntp->tzone);

+ 5 - 3
ip/src/websocket_handle.c

@@ -10,7 +10,9 @@
 #include "cascade.h"
 
 
-//#define USE_WS2
+#define USE_WS2
+#define WS_SEND_TLEN_MAX  (1024*1024*10)
+
 #define USE_ONE_CONN
 
 #define WS_MAX    10
@@ -46,7 +48,7 @@ static int ws_send(ws_handle_t *wh, void *data, int len, int isBinary)
         return -1;
     }
 #ifdef USE_WS2
-    mg_ws_send2(wh->c, data, len, isBinary?WEBSOCKET_OP_BINARY:WEBSOCKET_OP_TEXT);
+    mg_ws_send2(wh->c, data, len, isBinary?WEBSOCKET_OP_BINARY:WEBSOCKET_OP_TEXT,WS_SEND_TLEN_MAX);
 #else
     mg_ws_send(wh->c, data, len, isBinary?WEBSOCKET_OP_BINARY:WEBSOCKET_OP_TEXT);
 #endif
@@ -60,7 +62,7 @@ static int ws_broadcast(ws_handle_t *wh, void *data, int len, int isBinary)
 
     for (c=wh->mgr.conns; c!=NULL; c=c->next) {
 #ifdef USE_WS2
-        mg_ws_send2(c, data, len, isBinary?WEBSOCKET_OP_BINARY:WEBSOCKET_OP_TEXT);
+        mg_ws_send2(c, data, len, isBinary?WEBSOCKET_OP_BINARY:WEBSOCKET_OP_TEXT,WS_SEND_TLEN_MAX);
 #else
         mg_ws_send(c, data, len, isBinary?WEBSOCKET_OP_BINARY:WEBSOCKET_OP_TEXT);
 #endif