diff --git a/cmr/queries.py b/cmr/queries.py
index 3e4a1f9..328efe0 100644
--- a/cmr/queries.py
+++ b/cmr/queries.py
@@ -1186,7 +1186,9 @@ def get(self, limit: int = 2000) -> Sequence[Any]:
while len(results) < limit:
response = requests.get(
- url, params={"page_size": page_size, "page_num": page}
+ url,
+ headers=self.headers,
+ params={"page_size": page_size, "page_num": page},
)
response.raise_for_status()
diff --git a/tests/test_record_query_headers.py b/tests/test_record_query_headers.py
new file mode 100644
index 0000000..cc3f9ca
--- /dev/null
+++ b/tests/test_record_query_headers.py
@@ -0,0 +1,92 @@
+import json
+from unittest.mock import patch
+from urllib.parse import parse_qs, urlparse
+
+import pytest
+from requests import HTTPError, Response
+
+from cmr import ServiceQuery, ToolQuery, VariableQuery
+
+
+QUERY_CLASSES = [ToolQuery, ServiceQuery, VariableQuery]
+
+
+@pytest.fixture(autouse=True)
+def no_netrc_credentials():
+ # Do not pick up credentials from the test runner's home directory.
+ with patch("requests.sessions.get_netrc_auth", return_value=None):
+ yield
+
+
+def make_response(content: str, status: int = 200) -> Response:
+ response = Response()
+ response.status_code = status
+ response._content = content.encode("utf-8")
+ return response
+
+
+@pytest.mark.parametrize("query_class", QUERY_CLASSES)
+@pytest.mark.parametrize("auth_method", [None, "token", "bearer_token"])
+def test_get_sends_configured_headers_on_every_page(query_class, auth_method):
+ query = query_class()
+ query.headers.update(
+ {"Client-Id": "test-client", "X-Test-Header": "test-value"}
+ )
+ if auth_method:
+ getattr(query, auth_method)("test-token")
+ expected_headers = dict(query.headers)
+ first = {"name": "first"}
+ second = {"name": "second"}
+
+ with patch("requests.sessions.Session.send", autospec=True) as send:
+ send.side_effect = [
+ make_response(json.dumps({"items": [first]})),
+ make_response(json.dumps({"items": [second]})),
+ ]
+ assert query.get(2) == [first, second]
+
+ assert send.call_count == 2
+ for page, call in enumerate(send.call_args_list, start=1):
+ request = call.args[1]
+ assert request.method == "GET"
+ for name, value in expected_headers.items():
+ assert request.headers.get(name) == value
+ parameters = parse_qs(urlparse(request.url).query)
+ assert parameters["page_size"] == ["2"]
+ assert parameters["page_num"] == [str(page)]
+ assert query.headers == expected_headers
+
+
+@pytest.mark.parametrize("query_class", QUERY_CLASSES)
+def test_get_unparsed_pages_sends_configured_headers(query_class):
+ query = query_class().format("xml").bearer_token("test-token")
+ pages = ["first", "second"]
+ with patch("requests.sessions.Session.send", autospec=True) as send:
+ send.side_effect = [make_response(page) for page in pages]
+ assert query.get(2) == pages
+
+ assert send.call_count == 2
+ for call in send.call_args_list:
+ assert call.args[1].headers.get("Authorization") == "Bearer test-token"
+
+
+@pytest.mark.parametrize("query_class", QUERY_CLASSES)
+def test_get_without_headers_still_accepts_empty_results(query_class):
+ query = query_class()
+ with patch("requests.sessions.Session.send", autospec=True) as send:
+ send.return_value = make_response('{"items": []}')
+ assert query.get(2) == []
+ assert send.call_count == 1
+ assert "Authorization" not in send.call_args.args[1].headers
+ assert query.headers == {}
+
+
+@pytest.mark.parametrize("query_class", QUERY_CLASSES)
+def test_get_preserves_http_errors(query_class):
+ response = make_response("Forbidden", status=403)
+ with patch("requests.sessions.Session.send", autospec=True) as send:
+ send.return_value = response
+ with pytest.raises(HTTPError) as error:
+ query_class().bearer_token("test-token").get(1)
+ assert error.value.response is response
+ assert send.call_count == 1