Repository: django/daphne

Issue:
`Daphne` sets  `server='daphne'` header for `websocket` connections, but not for `http-requests`
# Hi there,

( Correct me if i am wrong here ) 
Daphne ( by default ) doesn't set a server header. 

By default these servers sets a header to identify backend technologies:
- [Uvicorn](github.com/encode/uvicorn) : uvicorn
- [Hypercorn](https://gitlab.com/pgjones/hypercorn) : hypercorn-{implementation}
- [Gunicorn](https://github.com/benoitc/gunicorn) : gunicorn/{version}

# Why should we do it ?
To allow technology detection by extensions like [Wappalyzer](https://github.com/AliasIO/wappalyzer/)

Comments:

Patch:
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 630c0fa..31e4650 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -11,7 +11,14 @@ Unreleased
   range of versions does not represent a good use of maintainer time. Going
   forward the latest Twisted version will be required.
 
-* Added `log-fmt` CLI argument.
+* Set ``daphne`` as default ``Server`` header.
+
+  This can be configured with the ``--server-name`` CLI argument.
+
+  Added the new ``--no-server-name`` CLI argument to disable the ``Server``
+  header, which is equivalent to ``--server-name=` (an empty name).
+
+* Added ``--log-fmt`` CLI argument.
 
 3.0.2 (2021-04-07)
 ------------------
diff --git a/daphne/cli.py b/daphne/cli.py
index 2e83a5c..accafe1 100755
--- a/daphne/cli.py
+++ b/daphne/cli.py
@@ -93,7 +93,7 @@ class CommandLineInterface:
         self.parser.add_argument(
             "--log-fmt",
             help="Log format to use",
-            default="%(asctime)-15s %(levelname)-8s %(message)s"
+            default="%(asctime)-15s %(levelname)-8s %(message)s",
         )
         self.parser.add_argument(
             "--ping-interval",
@@ -162,7 +162,10 @@ class CommandLineInterface:
             "--server-name",
             dest="server_name",
             help="specify which value should be passed to response header Server attribute",
-            default="Daphne",
+            default="daphne",
+        )
+        self.parser.add_argument(
+            "--no-server-name", dest="server_name", action="store_const", const=""
         )
 
         self.server = None
diff --git a/daphne/http_protocol.py b/daphne/http_protocol.py
index a289e93..f0657fd 100755
--- a/daphne/http_protocol.py
+++ b/daphne/http_protocol.py
@@ -249,8 +249,8 @@ class WebRequest(http.Request):
             # Write headers
             for header, value in message.get("headers", {}):
                 self.responseHeaders.addRawHeader(header, value)
-            if self.server.server_name and self.server.server_name.lower() != "daphne":
-                self.setHeader(b"server", self.server.server_name.encode("utf-8"))
+            if self.server.server_name and not self.responseHeaders.hasHeader("server"):
+                self.setHeader(b"server", self.server.server_name.encode())
             logger.debug(
                 "HTTP %s response started for %s", message["status"], self.client_addr
             )
diff --git a/daphne/server.py b/daphne/server.py
index 0d463d0..4334217 100755
--- a/daphne/server.py
+++ b/daphne/server.py
@@ -56,7 +56,7 @@ class Server:
         websocket_handshake_timeout=5,
         application_close_timeout=10,
         ready_callable=None,
-        server_name="Daphne",
+        server_name="daphne",
         # Deprecated and does not work, remove in version 2.2
         ws_protocols=None,
     ):


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 17335ed..51eab2e 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -240,3 +240,18 @@ class TestCLIInterface(TestCase):
             exc.exception.message,
             "--proxy-headers has to be passed for this parameter.",
         )
+
+    def test_custom_servername(self):
+        """
+        Passing `--server-name` will set the default server header
+        from 'daphne' to the passed one.
+        """
+        self.assertCLI([], {"server_name": "daphne"})
+        self.assertCLI(["--server-name", ""], {"server_name": ""})
+        self.assertCLI(["--server-name", "python"], {"server_name": "python"})
+
+    def test_no_servername(self):
+        """
+        Passing `--no-server-name` will set server name to '' (empty string)
+        """
+        self.assertCLI(["--no-server-name"], {"server_name": ""})
diff --git a/tests/test_http_response.py b/tests/test_http_response.py
index 1fc2439..22f6480 100644
--- a/tests/test_http_response.py
+++ b/tests/test_http_response.py
@@ -13,9 +13,12 @@ class TestHTTPResponse(DaphneTestCase):
         Lowercases and sorts headers, and strips transfer-encoding ones.
         """
         return sorted(
-            (name.lower(), value.strip())
-            for name, value in headers
-            if name.lower() != b"transfer-encoding"
+            [(b"server", b"daphne")]
+            + [
+                (name.lower(), value.strip())
+                for name, value in headers
+                if name.lower() not in (b"server", b"transfer-encoding")
+            ]
         )
 
     def encode_headers(self, headers):