浏览代码

Add TCP_USER_TIMEOUT to deal faster with broken connections.

Merge a similar fix from an old, MIT licensed clone:
https://code.google.com/r/bel2125-mongoose/source/browse/mongoose.c?spec=svn9a7158cc6b224ec1f75d19ca377a8af66b8fd873&r=9a7158cc6b224ec1f75d19ca377a8af66b8fd873
bel 10 年之前
父节点
当前提交
cb098f5bbd
共有 1 个文件被更改,包括 35 次插入9 次删除
  1. 35 9
      src/civetweb.c

+ 35 - 9
src/civetweb.c

@@ -1638,11 +1638,14 @@ static void send_http_error(struct mg_connection *conn, int status, const char *
         }
         DEBUG_TRACE("[%s]", buf);
 
-        mg_printf(conn, "HTTP/1.1 %d %s\r\n"
-                        "Content-Length: %d\r\n"
+        mg_printf(conn, "HTTP/1.1 %d %s\r\n", status, status_text);
+        if (len>0) {
+            mg_printf(conn, "Content-Type: text/plain\r\n");
+        }
+        mg_printf(conn, "Content-Length: %d\r\n"
                         "Date: %s\r\n"
                         "Connection: %s\r\n\r\n",
-                        status, status_text, len, date,
+                        len, date,
                         suggest_connection_header(conn));
         conn->num_bytes_sent += mg_printf(conn, "%s", buf);
     }
@@ -1818,13 +1821,19 @@ static void change_slashes_to_backslashes(char *path)
     int i;
 
     for (i = 0; path[i] != '\0'; i++) {
-        if (path[i] == '/')
+
+        if (path[i] == '/') {
             path[i] = '\\';
-        /* i > 0 check is to preserve UNC paths, like \\server\file.txt */
-        if (path[i] == '\\' && i > 0)
-            while (path[i + 1] == '\\' || path[i + 1] == '/')
+        }
+
+        /* remove double backslash (check i > 0 to preserve UNC paths, like \\server\file.txt) */
+        if ((path[i] == '\\') && (i > 0)) {
+
+            while (path[i + 1] == '\\' || path[i + 1] == '/') {
                 (void) memmove(path + i + 1,
                                path + i + 2, strlen(path + i + 1));
+            }
+        }
     }
 }
 
@@ -7499,15 +7508,32 @@ static void produce_socket(struct mg_context *ctx, const struct socket *sp)
 
 static int set_sock_timeout(SOCKET sock, int milliseconds)
 {
+    int r1, r2;
 #ifdef _WIN32
     DWORD t = milliseconds;
 #else
+    unsigned int uto = (unsigned int)milliseconds;
     struct timeval t;
     t.tv_sec = milliseconds / 1000;
     t.tv_usec = (milliseconds * 1000) % 1000000;
+
+    /* TCP_USER_TIMEOUT/RFC5482 (http://tools.ietf.org/html/rfc5482):
+       max. time waiting for the acknowledged of TCP data before the connection
+       will be forcefully closed and ETIMEDOUT is returned to the application.
+       If this option is not set, the default timeout of 20-30 minutes is used.
+    */
+    /* #define TCP_USER_TIMEOUT (18) */
+
+#if defined(TCP_USER_TIMEOUT)
+    setsockopt(sock, 6, TCP_USER_TIMEOUT, (const void *)&uto, sizeof(uto));
 #endif
-    return setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (SOCK_OPT_TYPE) &t, sizeof(t)) ||
-           setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (SOCK_OPT_TYPE) &t, sizeof(t));
+
+#endif
+
+    r1 = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (SOCK_OPT_TYPE) &t, sizeof(t));
+    r2 = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (SOCK_OPT_TYPE) &t, sizeof(t));
+
+    return r1 || r2;
 }
 
 static void accept_new_connection(const struct socket *listener,