diff --git a/include/ircd/resource/method.h b/include/ircd/resource/method.h index 35608c866..717ac2194 100644 --- a/include/ircd/resource/method.h +++ b/include/ircd/resource/method.h @@ -65,6 +65,9 @@ enum ircd::resource::method::flag /// This option prevents TCP nodelay from being toggled at the end of the /// request to flush the sendq; TCP delays are used by default. RESPONSE_NOFLUSH = 0x0008, + + /// This option TCP corks the response during the request. + RESPONSE_NOPUSH = 0x0010, }; struct ircd::resource::method::opts diff --git a/ircd/resource.cc b/ircd/resource.cc index 0f96b0c05..b7916a62f 100644 --- a/ircd/resource.cc +++ b/ircd/resource.cc @@ -603,6 +603,13 @@ try tokens(client.request.params, '/', client.request.param) }; + // Start the TCP cork if the method has this option set. + if(opts->flags & RESPONSE_NOPUSH) + { + assert(client.sock); + net::nopush(*client.sock, true); + } + // Finally handle the request. const auto &ret { @@ -612,6 +619,13 @@ try // Increment the successful completion counter for the handler. ++stats->completions; + // Stop the TCP cork if the method has this option set. + if(opts->flags & RESPONSE_NOPUSH) + { + assert(client.sock); + net::nopush(*client.sock, false); + } + // This branch flips TCP_NODELAY to force transmission here. This is a // good place because the request has finished writing everything; the // socket doesn't know that, but we do, and this is the place. The action