diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index f5e45e1961..515de0fa01 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -69,7 +69,7 @@ jobs: tags="${tag_year}.${tag_month}" if [[ "${tag_month}" == "12" ]]; then - tags+=",LTS" + tags+=",lts" echo "::notice::Tag ${tag} is LTS version" else echo "::notice::Tag ${tag} is not LTS version" @@ -122,7 +122,7 @@ jobs: name: Publish Docker / Python ${{ matrix.python-version }} needs: [generate_info, publish_package] runs-on: ubuntu-latest - if: ${{ needs.generate_info.IS_TEST == 'false' }} + if: ${{ needs.generate_info.outputs.is-test == 'false' }} strategy: fail-fast: true matrix: diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 0000000000..e0c660db18 --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,3 @@ +files: + - source: /guide/content/en/**/*.md + translation: /guide/content/%two_letters_code%/**/%original_file_name% diff --git a/readthedocs.yml b/readthedocs.yml index 87320098d0..f6a89418c9 100644 --- a/readthedocs.yml +++ b/readthedocs.yml @@ -1,9 +1,12 @@ version: 2 python: - version: 3.8 install: - method: pip path: . extra_requirements: - docs - system_packages: true + +build: + os: "ubuntu-22.04" + tools: + python: "3.8" diff --git a/sanic/helpers.py b/sanic/helpers.py index d7ac89680c..fbdac97f49 100644 --- a/sanic/helpers.py +++ b/sanic/helpers.py @@ -122,25 +122,6 @@ def is_hop_by_hop_header(header): return header.lower() in _HOP_BY_HOP_HEADERS -def remove_entity_headers(headers, allowed=("content-location", "expires")): - """ - Removes all the entity headers present in the headers given. - According to RFC 2616 Section 10.3.5, - Content-Location and Expires are allowed as for the - "strong cache validator". - https://tools.ietf.org/html/rfc2616#section-10.3.5 - - returns the headers without the entity headers - """ - allowed = set([h.lower() for h in allowed]) - headers = { - header: value - for header, value in headers.items() - if not is_entity_header(header) or header.lower() in allowed - } - return headers - - def import_string(module_name, package=None): """ import a module or class by string path. diff --git a/sanic/response/types.py b/sanic/response/types.py index 9d8a8e733a..8dbde38e30 100644 --- a/sanic/response/types.py +++ b/sanic/response/types.py @@ -24,7 +24,6 @@ Default, _default, has_message_body, - remove_entity_headers, ) from sanic.http import Http @@ -104,9 +103,6 @@ def processed_headers(self) -> Iterator[Tuple[bytes, bytes]]: Returns: Iterator[Tuple[bytes, bytes]]: A list of header tuples encoded in bytes for sending """ # noqa: E501 - # TODO: Make a blacklist set of header names and then filter with that - if self.status in (304, 412): # Not Modified, Precondition Failed - self.headers = remove_entity_headers(self.headers) if has_message_body(self.status): self.headers.setdefault("content-type", self.content_type) # Encode headers into bytes diff --git a/tests/test_helpers.py b/tests/test_helpers.py index cecdd7c689..8f62121bf5 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -41,28 +41,6 @@ def test_is_hop_by_hop_header(): assert helpers.is_hop_by_hop_header(header) is expected -def test_remove_entity_headers(): - tests = ( - ({}, {}), - ({"Allow": "GET, POST, HEAD"}, {}), - ( - { - "Content-Type": "application/json", - "Expires": "Wed, 21 Oct 2015 07:28:00 GMT", - "Foo": "Bar", - }, - {"Expires": "Wed, 21 Oct 2015 07:28:00 GMT", "Foo": "Bar"}, - ), - ( - {"Allow": "GET, POST, HEAD", "Content-Location": "/test"}, - {"Content-Location": "/test"}, - ), - ) - - for header, expected in tests: - assert helpers.remove_entity_headers(header) == expected - - def test_import_string_class(): obj = helpers.import_string("sanic.config.Config") assert isinstance(obj, Config) diff --git a/tests/test_response.py b/tests/test_response.py index 42180b6900..9f39b4e07a 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -178,6 +178,10 @@ async def no_content_unmodified_handler(request: Request): async def unmodified_handler(request: Request): return json(JSON_DATA, status=304) + @app.get("/precondition") + async def precondition_handler(request: Request): + return json(JSON_DATA, status=412) + @app.delete("/") async def delete_handler(request: Request): return json(None, status=204) @@ -193,6 +197,10 @@ def test_json_response(json_app): assert response.text == json_dumps(JSON_DATA) assert response.json == JSON_DATA + request, response = json_app.test_client.get("/precondition") + assert response.status == 412 + assert response.json == JSON_DATA + def test_no_content(json_app): request, response = json_app.test_client.get("/no-content")