浏览代码

Change option `tcp_nodelay` from boolean to number

This allows to implement a finer control over when to disable Nagle's algorithm.
See comment on #258
bel 9 年之前
父节点
当前提交
55eea8eb8d
共有 2 个文件被更改,包括 30 次插入15 次删除
  1. 8 5
      docs/UserManual.md
  2. 22 10
      src/civetweb.c

+ 8 - 5
docs/UserManual.md

@@ -382,13 +382,16 @@ must be called error404.ext, error4xx.ext or error.ext, whereas the file
 extention may be one of the extentions specified for the index_files option.
 extention may be one of the extentions specified for the index_files option.
 See the [Wikipedia page on HTTP status codes](http://en.wikipedia.org/wiki/HTTP_status_code).
 See the [Wikipedia page on HTTP status codes](http://en.wikipedia.org/wiki/HTTP_status_code).
 
 
-### tcp\_nodelay `no`
-Enable TCP_NODELAY socket option on client connections, either yes or no.
+### tcp\_nodelay `0`
+Enable TCP_NODELAY socket option on client connections.
 
 
-If set the socket option will disable Nagle's algorithm on the connection 
-which means that packets will be sent as soon as possible instead of waiting 
+If set the socket option will disable Nagle's algorithm on the connection
+which means that packets will be sent as soon as possible instead of waiting
 for a full buffer or timeout to occur.
 for a full buffer or timeout to occur.
 
 
+    0    Keep the default: Nagel's algorithm enabled
+    1    Disable Nagel's algorithm for all sockets
+
 ### decode\_url `yes`
 ### decode\_url `yes`
 URL encoded request strings are decoded in the server, unless it is disabled
 URL encoded request strings are decoded in the server, unless it is disabled
 by setting this option to `no`.
 by setting this option to `no`.
@@ -415,7 +418,7 @@ than the depth set here connection is refused.
 Loads default trusted certificates locations set at openssl compile time.
 Loads default trusted certificates locations set at openssl compile time.
 
 
 ### ssl_cipher_list
 ### ssl_cipher_list
-List of ciphers to present to the client. Entries should be separated by 
+List of ciphers to present to the client. Entries should be separated by
 colons, commas or spaces.
 colons, commas or spaces.
 
 
     ALL           All available ciphers
     ALL           All available ciphers

+ 22 - 10
src/civetweb.c

@@ -1168,7 +1168,7 @@ static struct mg_option config_options[] = {
 #endif
 #endif
     {"access_control_allow_origin", CONFIG_TYPE_STRING, "*"},
     {"access_control_allow_origin", CONFIG_TYPE_STRING, "*"},
     {"error_pages", CONFIG_TYPE_DIRECTORY, NULL},
     {"error_pages", CONFIG_TYPE_DIRECTORY, NULL},
-    {"tcp_nodelay", CONFIG_TYPE_BOOLEAN, "no"},
+    {"tcp_nodelay", CONFIG_TYPE_NUMBER, "0"},
 
 
     {NULL, CONFIG_TYPE_UNKNOWN, NULL}};
     {NULL, CONFIG_TYPE_UNKNOWN, NULL}};
 
 
@@ -10944,6 +10944,22 @@ set_sock_timeout(SOCKET sock, int milliseconds)
 }
 }
 
 
 
 
+static int
+set_tcp_nodelay(SOCKET sock, int nodelay_on)
+{
+	if (setsockopt(sock,
+	               IPPROTO_TCP,
+	               TCP_NODELAY,
+	               (SOCK_OPT_TYPE)&nodelay_on,
+	               sizeof(nodelay_on)) != 0) {
+		/* Error */
+		return 1;
+	}
+	/* OK */
+	return 0;
+}
+
+
 static void
 static void
 close_socket_gracefully(struct mg_connection *conn)
 close_socket_gracefully(struct mg_connection *conn)
 {
 {
@@ -12104,9 +12120,8 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 		 * keep-alive
 		 * keep-alive
 		 * is enabled, and client resets the connection, server won't get
 		 * is enabled, and client resets the connection, server won't get
 		 * TCP FIN or RST and will keep the connection open forever. With
 		 * TCP FIN or RST and will keep the connection open forever. With
-		 * TCP
-		 * keep-alive, next keep-alive handshake will figure out that the
-		 * client is down and will close the server end.
+		 * TCP keep-alive, next keep-alive handshake will figure out that
+		 * the client is down and will close the server end.
 		 * Thanks to Igor Klopov who suggested the patch. */
 		 * Thanks to Igor Klopov who suggested the patch. */
 		if (setsockopt(so.sock,
 		if (setsockopt(so.sock,
 		               SOL_SOCKET,
 		               SOL_SOCKET,
@@ -12127,12 +12142,9 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 		 * persistent connections are used and the responses are relatively
 		 * persistent connections are used and the responses are relatively
 		 * small (eg. less than 1400 bytes).
 		 * small (eg. less than 1400 bytes).
 		 */
 		 */
-		if (ctx && mg_strcasecmp(ctx->config[CONFIG_TCP_NODELAY], "yes") == 0) {
-			if (setsockopt(so.sock,
-			               IPPROTO_TCP,
-			               TCP_NODELAY,
-			               (SOCK_OPT_TYPE)&on,
-			               sizeof(on)) != 0) {
+		if ((ctx != NULL) && (ctx->config[CONFIG_TCP_NODELAY] != NULL)
+		    && (!strcmp(ctx->config[CONFIG_TCP_NODELAY], "1"))) {
+			if (set_tcp_nodelay(so.sock, 1) != 0) {
 				mg_cry(fc(ctx),
 				mg_cry(fc(ctx),
 				       "%s: setsockopt(IPPROTO_TCP TCP_NODELAY) failed: %s",
 				       "%s: setsockopt(IPPROTO_TCP TCP_NODELAY) failed: %s",
 				       __func__,
 				       __func__,