Repository: elastic/apm-agent-python

Issue:
"GET /" version sniffing request to APM server sets "content-encoding: gzip"
**Describe the bug**: 

On startup the Python APM agent's version-sniffing request to APM server looks like this:

```
    GET / HTTP/1.1
    host: localhost:8200
    accept-encoding: identity
    content-type: application/x-ndjson
    content-encoding: gzip
    user-agent: apm-agent-python/6.12.0 (unknown-python-service)
    accept: text/plain
```

I think the "content-encoding" and "content-type" are inappropriate. Clearly the real APM server is fine with this, but at least my lame-o "mockapmserver.js" crashed on this. I definitely need to make my mockapmserver code more bulletproof, but it might be work removing those headers from the version sniffing request.

vs. this from the Go agent:

```
    GET / HTTP/1.1
    host: localhost:8200
    user-agent: apm-agent-go/2.1.0 (trace-redis)
    accept-encoding: gzip
```

and this from the Node.js agent:

```
    GET / HTTP/1.1
    accept: application/json
    user-agent: apm-agent-nodejs/3.38.0 (all-the-rediss-nodejs 1.0.0)
    host: localhost:8200
    connection: close
```

**To Reproduce**

```
% cat foo.py
import elasticapm
client = elasticapm.Client()
elasticapm.instrument()

% python foo.py
```

**Environment (please complete the following information)**

- OS: macOS
- Python version: 3.10.2
- Framework and version [e.g. Django 2.1]: N/A
- APM Server version: mockapmserver.js ;)
- Agent version: elastic-apm   6.12.0




Discussion:

Resolving patch:
diff --git a/elasticapm/base.py b/elasticapm/base.py
--- a/elasticapm/base.py
+++ b/elasticapm/base.py
@@ -140,8 +140,6 @@ def __init__(self, config=None, **inline):
                 logging.setLogRecordFactory(new_factory)
 
         headers = {
-            "Content-Type": "application/x-ndjson",
-            "Content-Encoding": "gzip",
             "User-Agent": self.get_user_agent(),
         }
 
diff --git a/elasticapm/transport/http.py b/elasticapm/transport/http.py
--- a/elasticapm/transport/http.py
+++ b/elasticapm/transport/http.py
@@ -75,6 +75,12 @@ def send(self, data, forced_flush=False):
 
         headers = self._headers.copy() if self._headers else {}
         headers.update(self.auth_headers)
+        headers.update(
+            {
+                b"Content-Type": b"application/x-ndjson",
+                b"Content-Encoding": b"gzip",
+            }
+        )
 
         url = self._url
         if forced_flush:
@@ -146,7 +152,6 @@ def get_config(self, current_version=None, keys=None):
         data = json_encoder.dumps(keys).encode("utf-8")
         headers = self._headers.copy()
         headers[b"Content-Type"] = "application/json"
-        headers.pop(b"Content-Encoding", None)  # remove gzip content-encoding header
         headers.update(self.auth_headers)
         max_age = 300
         if current_version:
@@ -190,7 +195,7 @@ def _process_queue(self):
     def fetch_server_info(self):
         headers = self._headers.copy() if self._headers else {}
         headers.update(self.auth_headers)
-        headers["accept"] = "text/plain"
+        headers[b"accept"] = b"text/plain"
         try:
             response = self.http.urlopen("GET", self._server_info_url, headers=headers, timeout=self._timeout)
             body = response.data


Test patch:
diff --git a/tests/transports/test_urllib3.py b/tests/transports/test_urllib3.py
--- a/tests/transports/test_urllib3.py
+++ b/tests/transports/test_urllib3.py
@@ -50,12 +50,20 @@
 
 @pytest.mark.flaky(reruns=3)  # test is flaky on Windows
 def test_send(waiting_httpserver, elasticapm_client):
+    elasticapm_client.server_version = (8, 0)  # avoid making server_info request
     waiting_httpserver.serve_content(code=202, content="", headers={"Location": "http://example.com/foo"})
-    transport = Transport(waiting_httpserver.url, client=elasticapm_client)
+    transport = Transport(
+        waiting_httpserver.url, client=elasticapm_client, headers=elasticapm_client._transport._headers
+    )
     transport.start_thread()
     try:
         url = transport.send("x".encode("latin-1"))
         assert url == "http://example.com/foo"
+        request_headers = waiting_httpserver.requests[0].headers
+        assert request_headers["User-Agent"].startswith("apm-agent-python/")
+        assert request_headers["Authorization"] == "Bearer test_key"
+        assert request_headers["Content-Type"] == "application/x-ndjson"
+        assert request_headers["Content-Encoding"] == "gzip"
     finally:
         transport.close()
 
@@ -277,7 +285,7 @@ def test_get_config(waiting_httpserver, elasticapm_client):
     transport = Transport(
         url + "/" + constants.EVENTS_API_PATH,
         client=elasticapm_client,
-        headers={"Content-Type": "application/x-ndjson", "Content-Encoding": "gzip"},
+        headers=elasticapm_client._transport._headers,
     )
     version, data, max_age = transport.get_config("1", {})
     assert version == "2"
@@ -380,9 +388,16 @@ def test_fetch_server_info(waiting_httpserver, elasticapm_client):
         content=b'{"version": "8.0.0-alpha1"}',
     )
     url = waiting_httpserver.url
-    transport = Transport(url + "/" + constants.EVENTS_API_PATH, client=elasticapm_client)
+    transport = Transport(
+        url + "/" + constants.EVENTS_API_PATH, client=elasticapm_client, headers=elasticapm_client._transport._headers
+    )
     transport.fetch_server_info()
     assert elasticapm_client.server_version == (8, 0, 0, "alpha1")
+    request_headers = waiting_httpserver.requests[0].headers
+    assert request_headers["User-Agent"].startswith("apm-agent-python/")
+    assert "Authorization" in request_headers
+    assert "Content-Type" not in request_headers
+    assert "Content-Encoding" not in request_headers
 
 
 def test_fetch_server_info_no_json(waiting_httpserver, caplog, elasticapm_client):