We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Ensure cutoff date is updated
figure out when the cutoff date for ambiguous timestamps needs updating and either calculate it dynamically or add a unit test that fails when it needs adjusting.

https://github.com/scoutapp/scout_apm_python/blob/cf2246e6ff0dc1b69ffff25e10cd83782895ee27/src/scout_apm/core/web_requests.py#L149-L173

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/scout_apm/core/web_requests.py`
Content:
```
1 # coding=utf-8
2 from __future__ import absolute_import, division, print_function, unicode_literals
3 
4 import time
5 
6 from scout_apm.compat import datetime_to_timestamp, parse_qsl, urlencode
7 from scout_apm.core.config import scout_config
8 
9 # Originally derived from:
10 # 1. Rails:
11 #   https://github.com/rails/rails/blob/0196551e6039ca864d1eee1e01819fcae12c1dc9/railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt  # noqa
12 # 2. Sentry server side scrubbing:
13 #   https://docs.sentry.io/data-management/sensitive-data/#server-side-scrubbing
14 FILTER_PARAMETERS = frozenset(
15     [
16         "access",
17         "access_token",
18         "api_key",
19         "apikey",
20         "auth",
21         "auth_token",
22         "card[number]",
23         "certificate",
24         "credentials",
25         "crypt",
26         "key",
27         "mysql_pwd",
28         "otp",
29         "passwd",
30         "password",
31         "private",
32         "protected",
33         "salt",
34         "secret",
35         "ssn",
36         "stripetoken",
37         "token",
38     ]
39 )
40 
41 
42 def create_filtered_path(path, query_params):
43     if scout_config.value("uri_reporting") == "path":
44         return path
45     # Python 2 unicode compatibility: force all keys and values to bytes
46     filtered_params = sorted(
47         (
48             (
49                 key.encode("utf-8"),
50                 (
51                     b"[FILTERED]"
52                     if key.lower() in FILTER_PARAMETERS
53                     else value.encode("utf-8")
54                 ),
55             )
56             for key, value in query_params
57         )
58     )
59     if not filtered_params:
60         return path
61     return path + "?" + urlencode(filtered_params)
62 
63 
64 def ignore_path(path):
65     ignored_paths = scout_config.value("ignore")
66     for ignored in ignored_paths:
67         if path.startswith(ignored):
68             return True
69     return False
70 
71 
72 def track_request_queue_time(header_value, tracked_request):
73     if header_value.startswith("t="):
74         header_value = header_value[2:]
75 
76     try:
77         first_char = header_value[0]
78     except IndexError:
79         return False
80 
81     if not first_char.isdigit():  # filter out negatives, nan, inf, etc.
82         return False
83 
84     try:
85         ambiguous_start_timestamp = float(header_value)
86     except ValueError:
87         return False
88 
89     start_timestamp_ns = convert_ambiguous_timestamp_to_ns(ambiguous_start_timestamp)
90     if start_timestamp_ns == 0.0:
91         return False
92 
93     tr_start_timestamp_ns = datetime_to_timestamp(tracked_request.start_time) * 1e9
94 
95     # Ignore if in the future
96     if start_timestamp_ns > tr_start_timestamp_ns:
97         return False
98 
99     queue_time_ns = int(tr_start_timestamp_ns - start_timestamp_ns)
100     tracked_request.tag("scout.queue_time_ns", queue_time_ns)
101     return True
102 
103 
104 def track_amazon_request_queue_time(header_value, tracked_request):
105     items = header_value.split(";")
106     found_item = None
107     for item in items:
108         if found_item is None and item.startswith("Root="):
109             found_item = item
110         elif item.startswith("Self="):
111             found_item = item
112 
113     if found_item is None:
114         return False
115 
116     pieces = found_item.split("-")
117     if len(pieces) != 3:
118         return False
119 
120     timestamp_str = pieces[1]
121 
122     try:
123         first_char = timestamp_str[0]
124     except IndexError:
125         return False
126 
127     if not first_char.isdigit():
128         return False
129 
130     try:
131         start_timestamp_ns = int(timestamp_str) * 1000000000.0
132     except ValueError:
133         return False
134 
135     if start_timestamp_ns == 0:
136         return False
137 
138     tr_start_timestamp_ns = datetime_to_timestamp(tracked_request.start_time) * 1e9
139 
140     # Ignore if in the futuren
141     if start_timestamp_ns > tr_start_timestamp_ns:
142         return False
143 
144     queue_time_ns = int(tr_start_timestamp_ns - start_timestamp_ns)
145     tracked_request.tag("scout.queue_time_ns", queue_time_ns)
146     return True
147 
148 
149 # Cutoff epoch is used for determining ambiguous timestamp boundaries, and is
150 # just over 10 years ago at time of writing
151 CUTOFF_EPOCH_S = time.mktime((2009, 6, 1, 0, 0, 0, 0, 0, 0))
152 CUTOFF_EPOCH_MS = CUTOFF_EPOCH_S * 1000.0
153 CUTOFF_EPOCH_US = CUTOFF_EPOCH_S * 1000000.0
154 CUTOFF_EPOCH_NS = CUTOFF_EPOCH_S * 1000000000.0
155 
156 
157 def convert_ambiguous_timestamp_to_ns(timestamp):
158     """
159     Convert an ambiguous float timestamp that could be in nanoseconds,
160     microseconds, milliseconds, or seconds to nanoseconds. Return 0.0 for
161     values in the more than 10 years ago.
162     """
163     if timestamp > CUTOFF_EPOCH_NS:
164         converted_timestamp = timestamp
165     elif timestamp > CUTOFF_EPOCH_US:
166         converted_timestamp = timestamp * 1000.0
167     elif timestamp > CUTOFF_EPOCH_MS:
168         converted_timestamp = timestamp * 1000000.0
169     elif timestamp > CUTOFF_EPOCH_S:
170         converted_timestamp = timestamp * 1000000000.0
171     else:
172         return 0.0
173     return converted_timestamp
174 
175 
176 def asgi_track_request_data(scope, tracked_request):
177     """
178     Track request data from an ASGI HTTP or Websocket scope.
179     """
180     path = scope.get("root_path", "") + scope["path"]
181     query_params = parse_qsl(scope.get("query_string", b"").decode("utf-8"))
182     tracked_request.tag("path", create_filtered_path(path, query_params))
183     if ignore_path(path):
184         tracked_request.tag("ignore_transaction", True)
185 
186     # We only care about the last values of headers so don't care that we use
187     # a plain dict rather than a multi-value dict
188     headers = {k.lower(): v for k, v in scope.get("headers", ())}
189 
190     user_ip = (
191         headers.get(b"x-forwarded-for", b"").decode("latin1").split(",")[0]
192         or headers.get(b"client-ip", b"").decode("latin1").split(",")[0]
193         or scope.get("client", ("",))[0]
194     )
195     tracked_request.tag("user_ip", user_ip)
196 
197     queue_time = headers.get(b"x-queue-start", b"") or headers.get(
198         b"x-request-start", b""
199     )
200     tracked_queue_time = track_request_queue_time(
201         queue_time.decode("latin1"), tracked_request
202     )
203     if not tracked_queue_time:
204         amazon_queue_time = headers.get(b"x-amzn-trace-id", b"")
205         track_amazon_request_queue_time(
206             amazon_queue_time.decode("latin1"), tracked_request
207         )
208 
209 
210 def werkzeug_track_request_data(werkzeug_request, tracked_request):
211     """
212     Several integrations use Werkzeug requests, so share the code for
213     extracting common data here.
214     """
215     path = werkzeug_request.path
216     tracked_request.tag(
217         "path", create_filtered_path(path, werkzeug_request.args.items(multi=True))
218     )
219     if ignore_path(path):
220         tracked_request.tag("ignore_transaction", True)
221 
222     # Determine a remote IP to associate with the request. The value is
223     # spoofable by the requester so this is not suitable to use in any
224     # security sensitive context.
225     user_ip = (
226         werkzeug_request.headers.get("x-forwarded-for", default="").split(",")[0]
227         or werkzeug_request.headers.get("client-ip", default="").split(",")[0]
228         or werkzeug_request.remote_addr
229     )
230     tracked_request.tag("user_ip", user_ip)
231 
232     queue_time = werkzeug_request.headers.get(
233         "x-queue-start", default=""
234     ) or werkzeug_request.headers.get("x-request-start", default="")
235     tracked_queue_time = track_request_queue_time(queue_time, tracked_request)
236     if not tracked_queue_time:
237         amazon_queue_time = werkzeug_request.headers.get("x-amzn-trace-id", default="")
238         track_amazon_request_queue_time(amazon_queue_time, tracked_request)
239
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/scout_apm/core/web_requests.py b/src/scout_apm/core/web_requests.py
--- a/src/scout_apm/core/web_requests.py
+++ b/src/scout_apm/core/web_requests.py
@@ -1,6 +1,7 @@
 # coding=utf-8
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+import datetime as dt
 import time
 
 from scout_apm.compat import datetime_to_timestamp, parse_qsl, urlencode
@@ -146,9 +147,8 @@
     return True
 
 
-# Cutoff epoch is used for determining ambiguous timestamp boundaries, and is
-# just over 10 years ago at time of writing
-CUTOFF_EPOCH_S = time.mktime((2009, 6, 1, 0, 0, 0, 0, 0, 0))
+# Cutoff epoch is used for determining ambiguous timestamp boundaries
+CUTOFF_EPOCH_S = time.mktime((dt.date.today().year - 10, 1, 1, 0, 0, 0, 0, 0, 0))
 CUTOFF_EPOCH_MS = CUTOFF_EPOCH_S * 1000.0
 CUTOFF_EPOCH_US = CUTOFF_EPOCH_S * 1000000.0
 CUTOFF_EPOCH_NS = CUTOFF_EPOCH_S * 1000000000.0

{"golden_diff": "diff --git a/src/scout_apm/core/web_requests.py b/src/scout_apm/core/web_requests.py\n--- a/src/scout_apm/core/web_requests.py\n+++ b/src/scout_apm/core/web_requests.py\n@@ -1,6 +1,7 @@\n # coding=utf-8\n from __future__ import absolute_import, division, print_function, unicode_literals\n \n+import datetime as dt\n import time\n \n from scout_apm.compat import datetime_to_timestamp, parse_qsl, urlencode\n@@ -146,9 +147,8 @@\n     return True\n \n \n-# Cutoff epoch is used for determining ambiguous timestamp boundaries, and is\n-# just over 10 years ago at time of writing\n-CUTOFF_EPOCH_S = time.mktime((2009, 6, 1, 0, 0, 0, 0, 0, 0))\n+# Cutoff epoch is used for determining ambiguous timestamp boundaries\n+CUTOFF_EPOCH_S = time.mktime((dt.date.today().year - 10, 1, 1, 0, 0, 0, 0, 0, 0))\n CUTOFF_EPOCH_MS = CUTOFF_EPOCH_S * 1000.0\n CUTOFF_EPOCH_US = CUTOFF_EPOCH_S * 1000000.0\n CUTOFF_EPOCH_NS = CUTOFF_EPOCH_S * 1000000000.0\n", "issue": "Ensure cutoff date is updated\nfigure out when the cutoff date for ambiguous timestamps needs updating and either calculate it dynamically or add a unit test that fails when it needs adjusting.\r\n\r\nhttps://github.com/scoutapp/scout_apm_python/blob/cf2246e6ff0dc1b69ffff25e10cd83782895ee27/src/scout_apm/core/web_requests.py#L149-L173\n", "before_files": [{"content": "# coding=utf-8\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport time\n\nfrom scout_apm.compat import datetime_to_timestamp, parse_qsl, urlencode\nfrom scout_apm.core.config import scout_config\n\n# Originally derived from:\n# 1. Rails:\n#   https://github.com/rails/rails/blob/0196551e6039ca864d1eee1e01819fcae12c1dc9/railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt  # noqa\n# 2. Sentry server side scrubbing:\n#   https://docs.sentry.io/data-management/sensitive-data/#server-side-scrubbing\nFILTER_PARAMETERS = frozenset(\n    [\n        \"access\",\n        \"access_token\",\n        \"api_key\",\n        \"apikey\",\n        \"auth\",\n        \"auth_token\",\n        \"card[number]\",\n        \"certificate\",\n        \"credentials\",\n        \"crypt\",\n        \"key\",\n        \"mysql_pwd\",\n        \"otp\",\n        \"passwd\",\n        \"password\",\n        \"private\",\n        \"protected\",\n        \"salt\",\n        \"secret\",\n        \"ssn\",\n        \"stripetoken\",\n        \"token\",\n    ]\n)\n\n\ndef create_filtered_path(path, query_params):\n    if scout_config.value(\"uri_reporting\") == \"path\":\n        return path\n    # Python 2 unicode compatibility: force all keys and values to bytes\n    filtered_params = sorted(\n        (\n            (\n                key.encode(\"utf-8\"),\n                (\n                    b\"[FILTERED]\"\n                    if key.lower() in FILTER_PARAMETERS\n                    else value.encode(\"utf-8\")\n                ),\n            )\n            for key, value in query_params\n        )\n    )\n    if not filtered_params:\n        return path\n    return path + \"?\" + urlencode(filtered_params)\n\n\ndef ignore_path(path):\n    ignored_paths = scout_config.value(\"ignore\")\n    for ignored in ignored_paths:\n        if path.startswith(ignored):\n            return True\n    return False\n\n\ndef track_request_queue_time(header_value, tracked_request):\n    if header_value.startswith(\"t=\"):\n        header_value = header_value[2:]\n\n    try:\n        first_char = header_value[0]\n    except IndexError:\n        return False\n\n    if not first_char.isdigit():  # filter out negatives, nan, inf, etc.\n        return False\n\n    try:\n        ambiguous_start_timestamp = float(header_value)\n    except ValueError:\n        return False\n\n    start_timestamp_ns = convert_ambiguous_timestamp_to_ns(ambiguous_start_timestamp)\n    if start_timestamp_ns == 0.0:\n        return False\n\n    tr_start_timestamp_ns = datetime_to_timestamp(tracked_request.start_time) * 1e9\n\n    # Ignore if in the future\n    if start_timestamp_ns > tr_start_timestamp_ns:\n        return False\n\n    queue_time_ns = int(tr_start_timestamp_ns - start_timestamp_ns)\n    tracked_request.tag(\"scout.queue_time_ns\", queue_time_ns)\n    return True\n\n\ndef track_amazon_request_queue_time(header_value, tracked_request):\n    items = header_value.split(\";\")\n    found_item = None\n    for item in items:\n        if found_item is None and item.startswith(\"Root=\"):\n            found_item = item\n        elif item.startswith(\"Self=\"):\n            found_item = item\n\n    if found_item is None:\n        return False\n\n    pieces = found_item.split(\"-\")\n    if len(pieces) != 3:\n        return False\n\n    timestamp_str = pieces[1]\n\n    try:\n        first_char = timestamp_str[0]\n    except IndexError:\n        return False\n\n    if not first_char.isdigit():\n        return False\n\n    try:\n        start_timestamp_ns = int(timestamp_str) * 1000000000.0\n    except ValueError:\n        return False\n\n    if start_timestamp_ns == 0:\n        return False\n\n    tr_start_timestamp_ns = datetime_to_timestamp(tracked_request.start_time) * 1e9\n\n    # Ignore if in the futuren\n    if start_timestamp_ns > tr_start_timestamp_ns:\n        return False\n\n    queue_time_ns = int(tr_start_timestamp_ns - start_timestamp_ns)\n    tracked_request.tag(\"scout.queue_time_ns\", queue_time_ns)\n    return True\n\n\n# Cutoff epoch is used for determining ambiguous timestamp boundaries, and is\n# just over 10 years ago at time of writing\nCUTOFF_EPOCH_S = time.mktime((2009, 6, 1, 0, 0, 0, 0, 0, 0))\nCUTOFF_EPOCH_MS = CUTOFF_EPOCH_S * 1000.0\nCUTOFF_EPOCH_US = CUTOFF_EPOCH_S * 1000000.0\nCUTOFF_EPOCH_NS = CUTOFF_EPOCH_S * 1000000000.0\n\n\ndef convert_ambiguous_timestamp_to_ns(timestamp):\n    \"\"\"\n    Convert an ambiguous float timestamp that could be in nanoseconds,\n    microseconds, milliseconds, or seconds to nanoseconds. Return 0.0 for\n    values in the more than 10 years ago.\n    \"\"\"\n    if timestamp > CUTOFF_EPOCH_NS:\n        converted_timestamp = timestamp\n    elif timestamp > CUTOFF_EPOCH_US:\n        converted_timestamp = timestamp * 1000.0\n    elif timestamp > CUTOFF_EPOCH_MS:\n        converted_timestamp = timestamp * 1000000.0\n    elif timestamp > CUTOFF_EPOCH_S:\n        converted_timestamp = timestamp * 1000000000.0\n    else:\n        return 0.0\n    return converted_timestamp\n\n\ndef asgi_track_request_data(scope, tracked_request):\n    \"\"\"\n    Track request data from an ASGI HTTP or Websocket scope.\n    \"\"\"\n    path = scope.get(\"root_path\", \"\") + scope[\"path\"]\n    query_params = parse_qsl(scope.get(\"query_string\", b\"\").decode(\"utf-8\"))\n    tracked_request.tag(\"path\", create_filtered_path(path, query_params))\n    if ignore_path(path):\n        tracked_request.tag(\"ignore_transaction\", True)\n\n    # We only care about the last values of headers so don't care that we use\n    # a plain dict rather than a multi-value dict\n    headers = {k.lower(): v for k, v in scope.get(\"headers\", ())}\n\n    user_ip = (\n        headers.get(b\"x-forwarded-for\", b\"\").decode(\"latin1\").split(\",\")[0]\n        or headers.get(b\"client-ip\", b\"\").decode(\"latin1\").split(\",\")[0]\n        or scope.get(\"client\", (\"\",))[0]\n    )\n    tracked_request.tag(\"user_ip\", user_ip)\n\n    queue_time = headers.get(b\"x-queue-start\", b\"\") or headers.get(\n        b\"x-request-start\", b\"\"\n    )\n    tracked_queue_time = track_request_queue_time(\n        queue_time.decode(\"latin1\"), tracked_request\n    )\n    if not tracked_queue_time:\n        amazon_queue_time = headers.get(b\"x-amzn-trace-id\", b\"\")\n        track_amazon_request_queue_time(\n            amazon_queue_time.decode(\"latin1\"), tracked_request\n        )\n\n\ndef werkzeug_track_request_data(werkzeug_request, tracked_request):\n    \"\"\"\n    Several integrations use Werkzeug requests, so share the code for\n    extracting common data here.\n    \"\"\"\n    path = werkzeug_request.path\n    tracked_request.tag(\n        \"path\", create_filtered_path(path, werkzeug_request.args.items(multi=True))\n    )\n    if ignore_path(path):\n        tracked_request.tag(\"ignore_transaction\", True)\n\n    # Determine a remote IP to associate with the request. The value is\n    # spoofable by the requester so this is not suitable to use in any\n    # security sensitive context.\n    user_ip = (\n        werkzeug_request.headers.get(\"x-forwarded-for\", default=\"\").split(\",\")[0]\n        or werkzeug_request.headers.get(\"client-ip\", default=\"\").split(\",\")[0]\n        or werkzeug_request.remote_addr\n    )\n    tracked_request.tag(\"user_ip\", user_ip)\n\n    queue_time = werkzeug_request.headers.get(\n        \"x-queue-start\", default=\"\"\n    ) or werkzeug_request.headers.get(\"x-request-start\", default=\"\")\n    tracked_queue_time = track_request_queue_time(queue_time, tracked_request)\n    if not tracked_queue_time:\n        amazon_queue_time = werkzeug_request.headers.get(\"x-amzn-trace-id\", default=\"\")\n        track_amazon_request_queue_time(amazon_queue_time, tracked_request)\n", "path": "src/scout_apm/core/web_requests.py"}], "after_files": [{"content": "# coding=utf-8\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport datetime as dt\nimport time\n\nfrom scout_apm.compat import datetime_to_timestamp, parse_qsl, urlencode\nfrom scout_apm.core.config import scout_config\n\n# Originally derived from:\n# 1. Rails:\n#   https://github.com/rails/rails/blob/0196551e6039ca864d1eee1e01819fcae12c1dc9/railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt  # noqa\n# 2. Sentry server side scrubbing:\n#   https://docs.sentry.io/data-management/sensitive-data/#server-side-scrubbing\nFILTER_PARAMETERS = frozenset(\n    [\n        \"access\",\n        \"access_token\",\n        \"api_key\",\n        \"apikey\",\n        \"auth\",\n        \"auth_token\",\n        \"card[number]\",\n        \"certificate\",\n        \"credentials\",\n        \"crypt\",\n        \"key\",\n        \"mysql_pwd\",\n        \"otp\",\n        \"passwd\",\n        \"password\",\n        \"private\",\n        \"protected\",\n        \"salt\",\n        \"secret\",\n        \"ssn\",\n        \"stripetoken\",\n        \"token\",\n    ]\n)\n\n\ndef create_filtered_path(path, query_params):\n    if scout_config.value(\"uri_reporting\") == \"path\":\n        return path\n    # Python 2 unicode compatibility: force all keys and values to bytes\n    filtered_params = sorted(\n        (\n            (\n                key.encode(\"utf-8\"),\n                (\n                    b\"[FILTERED]\"\n                    if key.lower() in FILTER_PARAMETERS\n                    else value.encode(\"utf-8\")\n                ),\n            )\n            for key, value in query_params\n        )\n    )\n    if not filtered_params:\n        return path\n    return path + \"?\" + urlencode(filtered_params)\n\n\ndef ignore_path(path):\n    ignored_paths = scout_config.value(\"ignore\")\n    for ignored in ignored_paths:\n        if path.startswith(ignored):\n            return True\n    return False\n\n\ndef track_request_queue_time(header_value, tracked_request):\n    if header_value.startswith(\"t=\"):\n        header_value = header_value[2:]\n\n    try:\n        first_char = header_value[0]\n    except IndexError:\n        return False\n\n    if not first_char.isdigit():  # filter out negatives, nan, inf, etc.\n        return False\n\n    try:\n        ambiguous_start_timestamp = float(header_value)\n    except ValueError:\n        return False\n\n    start_timestamp_ns = convert_ambiguous_timestamp_to_ns(ambiguous_start_timestamp)\n    if start_timestamp_ns == 0.0:\n        return False\n\n    tr_start_timestamp_ns = datetime_to_timestamp(tracked_request.start_time) * 1e9\n\n    # Ignore if in the future\n    if start_timestamp_ns > tr_start_timestamp_ns:\n        return False\n\n    queue_time_ns = int(tr_start_timestamp_ns - start_timestamp_ns)\n    tracked_request.tag(\"scout.queue_time_ns\", queue_time_ns)\n    return True\n\n\ndef track_amazon_request_queue_time(header_value, tracked_request):\n    items = header_value.split(\";\")\n    found_item = None\n    for item in items:\n        if found_item is None and item.startswith(\"Root=\"):\n            found_item = item\n        elif item.startswith(\"Self=\"):\n            found_item = item\n\n    if found_item is None:\n        return False\n\n    pieces = found_item.split(\"-\")\n    if len(pieces) != 3:\n        return False\n\n    timestamp_str = pieces[1]\n\n    try:\n        first_char = timestamp_str[0]\n    except IndexError:\n        return False\n\n    if not first_char.isdigit():\n        return False\n\n    try:\n        start_timestamp_ns = int(timestamp_str) * 1000000000.0\n    except ValueError:\n        return False\n\n    if start_timestamp_ns == 0:\n        return False\n\n    tr_start_timestamp_ns = datetime_to_timestamp(tracked_request.start_time) * 1e9\n\n    # Ignore if in the futuren\n    if start_timestamp_ns > tr_start_timestamp_ns:\n        return False\n\n    queue_time_ns = int(tr_start_timestamp_ns - start_timestamp_ns)\n    tracked_request.tag(\"scout.queue_time_ns\", queue_time_ns)\n    return True\n\n\n# Cutoff epoch is used for determining ambiguous timestamp boundaries\nCUTOFF_EPOCH_S = time.mktime((dt.date.today().year - 10, 1, 1, 0, 0, 0, 0, 0, 0))\nCUTOFF_EPOCH_MS = CUTOFF_EPOCH_S * 1000.0\nCUTOFF_EPOCH_US = CUTOFF_EPOCH_S * 1000000.0\nCUTOFF_EPOCH_NS = CUTOFF_EPOCH_S * 1000000000.0\n\n\ndef convert_ambiguous_timestamp_to_ns(timestamp):\n    \"\"\"\n    Convert an ambiguous float timestamp that could be in nanoseconds,\n    microseconds, milliseconds, or seconds to nanoseconds. Return 0.0 for\n    values in the more than 10 years ago.\n    \"\"\"\n    if timestamp > CUTOFF_EPOCH_NS:\n        converted_timestamp = timestamp\n    elif timestamp > CUTOFF_EPOCH_US:\n        converted_timestamp = timestamp * 1000.0\n    elif timestamp > CUTOFF_EPOCH_MS:\n        converted_timestamp = timestamp * 1000000.0\n    elif timestamp > CUTOFF_EPOCH_S:\n        converted_timestamp = timestamp * 1000000000.0\n    else:\n        return 0.0\n    return converted_timestamp\n\n\ndef asgi_track_request_data(scope, tracked_request):\n    \"\"\"\n    Track request data from an ASGI HTTP or Websocket scope.\n    \"\"\"\n    path = scope.get(\"root_path\", \"\") + scope[\"path\"]\n    query_params = parse_qsl(scope.get(\"query_string\", b\"\").decode(\"utf-8\"))\n    tracked_request.tag(\"path\", create_filtered_path(path, query_params))\n    if ignore_path(path):\n        tracked_request.tag(\"ignore_transaction\", True)\n\n    # We only care about the last values of headers so don't care that we use\n    # a plain dict rather than a multi-value dict\n    headers = {k.lower(): v for k, v in scope.get(\"headers\", ())}\n\n    user_ip = (\n        headers.get(b\"x-forwarded-for\", b\"\").decode(\"latin1\").split(\",\")[0]\n        or headers.get(b\"client-ip\", b\"\").decode(\"latin1\").split(\",\")[0]\n        or scope.get(\"client\", (\"\",))[0]\n    )\n    tracked_request.tag(\"user_ip\", user_ip)\n\n    queue_time = headers.get(b\"x-queue-start\", b\"\") or headers.get(\n        b\"x-request-start\", b\"\"\n    )\n    tracked_queue_time = track_request_queue_time(\n        queue_time.decode(\"latin1\"), tracked_request\n    )\n    if not tracked_queue_time:\n        amazon_queue_time = headers.get(b\"x-amzn-trace-id\", b\"\")\n        track_amazon_request_queue_time(\n            amazon_queue_time.decode(\"latin1\"), tracked_request\n        )\n\n\ndef werkzeug_track_request_data(werkzeug_request, tracked_request):\n    \"\"\"\n    Several integrations use Werkzeug requests, so share the code for\n    extracting common data here.\n    \"\"\"\n    path = werkzeug_request.path\n    tracked_request.tag(\n        \"path\", create_filtered_path(path, werkzeug_request.args.items(multi=True))\n    )\n    if ignore_path(path):\n        tracked_request.tag(\"ignore_transaction\", True)\n\n    # Determine a remote IP to associate with the request. The value is\n    # spoofable by the requester so this is not suitable to use in any\n    # security sensitive context.\n    user_ip = (\n        werkzeug_request.headers.get(\"x-forwarded-for\", default=\"\").split(\",\")[0]\n        or werkzeug_request.headers.get(\"client-ip\", default=\"\").split(\",\")[0]\n        or werkzeug_request.remote_addr\n    )\n    tracked_request.tag(\"user_ip\", user_ip)\n\n    queue_time = werkzeug_request.headers.get(\n        \"x-queue-start\", default=\"\"\n    ) or werkzeug_request.headers.get(\"x-request-start\", default=\"\")\n    tracked_queue_time = track_request_queue_time(queue_time, tracked_request)\n    if not tracked_queue_time:\n        amazon_queue_time = werkzeug_request.headers.get(\"x-amzn-trace-id\", default=\"\")\n        track_amazon_request_queue_time(amazon_queue_time, tracked_request)\n", "path": "src/scout_apm/core/web_requests.py"}]}