Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,15 @@ on:
jobs:
build:

runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
matrix:
python:
- "3.6"
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- pypy-3.6
- pypy-3.7
- pypy-3.8
- pypy-3.9
- pypy-3.10
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ htmlcov
*.log
*.bak
*.backup

# Environments
.venv
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ Installation and usage
The following requirements are supported and tested in all reasonable
combinations:

- Python versions: 3.6–3.12
- Python versions: 3.8–3.12
- Interpreters: CPython and PyPy.
- Django versions: 1.11–5.0
- Django versions: 3.2–5.0

.. code:: shell

Expand Down
1 change: 0 additions & 1 deletion compression_middleware/br.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- encoding: utf-8 -*-
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down
3 changes: 1 addition & 2 deletions compression_middleware/middleware.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- encoding: utf-8 -*-
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down Expand Up @@ -79,7 +78,7 @@ def encoding_name(s):
def compressor(accept_encoding):
# We don't want to process extremely long headers. It might be an attack:
accept_encoding = accept_encoding[:200]
client_encodings = set(encoding_name(e) for e in accept_encoding.split(","))
client_encodings = {encoding_name(e) for e in accept_encoding.split(",")}
if "*" in client_encodings:
# Our first choice:
return compressors[0]
Expand Down
1 change: 0 additions & 1 deletion compression_middleware/zstd.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- encoding: utf-8 -*-
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
Expand Down
10 changes: 2 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,22 @@
author_email='friedel@translate.org.za',
packages=['compression_middleware'],
install_requires=install_requires,
python_requires=">=3.8",
include_package_data=True,
zip_safe=True,
classifiers=[
'Development Status :: 4 - Beta',
'Framework :: Django',
'Framework :: Django :: 1.11',
'Framework :: Django :: 2.0',
'Framework :: Django :: 2.1',
'Framework :: Django :: 2.2',
'Framework :: Django :: 3.0',
'Framework :: Django :: 3.1',
'Framework :: Django :: 3.2',
'Framework :: Django :: 4.0',
'Framework :: Django :: 4.1',
'Framework :: Django :: 4.2',
'Framework :: Django :: 5.0',
'Framework :: Django :: 5.1',
'Intended Audience :: Developers',
'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)',
'Natural Language :: English',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
Expand Down
3 changes: 0 additions & 3 deletions tests/test_decorator.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals

import brotli

from django.http import HttpRequest, HttpResponse, StreamingHttpResponse
Expand Down
15 changes: 2 additions & 13 deletions tests/test_interactions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals


# This tests if the middleware works as Django expects from its own
# GZipMiddleware. This way we test the expected interactions with other parts
# of Django, such as ConditionalGetMiddleware, which relies on certain parts
Expand All @@ -13,6 +9,7 @@

import gzip
import random
import struct
from io import BytesIO

from django.http import (
Expand All @@ -24,15 +21,7 @@
from django.middleware.http import ConditionalGetMiddleware
from django.test import RequestFactory, SimpleTestCase, override_settings

try:
# Python 2
range = xrange
int2byte = chr
except NameError:
# Python 3
import struct

int2byte = struct.Struct(">B").pack
int2byte = struct.Struct(">B").pack


class GZipMiddlewareTest(SimpleTestCase):
Expand Down
24 changes: 8 additions & 16 deletions tests/test_middleware.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# -*- encoding: utf-8 -*-

# partially based on tests in django and django-brotli

from io import BytesIO
import gzip
import random
from unittest import TestCase
import struct

import brotli
import zstandard as zstd
Expand All @@ -17,38 +16,31 @@

from django.middleware.gzip import GZipMiddleware
from django.test import RequestFactory, SimpleTestCase
try:
# Python 2
range = xrange
int2byte = chr
except NameError:
# Python 3
import struct
int2byte = struct.Struct(">B").pack

from compression_middleware.middleware import CompressionMiddleware, compressor
from .utils import UTF8_LOREM_IPSUM_IN_CZECH

int2byte = struct.Struct(">B").pack

class FakeRequestAcceptsZstd(object):
class FakeRequestAcceptsZstd:
META = {
"HTTP_ACCEPT_ENCODING": "gzip, deflate, sdch, br, zstd"
}


class FakeRequestAcceptsBrotli(object):
class FakeRequestAcceptsBrotli:
META = {
"HTTP_ACCEPT_ENCODING": "gzip, deflate, sdch, br"
}


class InvalidAcceptEcondingRequest(object):
class InvalidAcceptEcondingRequest:
META = {
"HTTP_ACCEPT_ENCODING": "text/plain,*/*; charset=utf-8"
}


class FakeLegacyRequest(object):
class FakeLegacyRequest:
META = {
}

Expand All @@ -58,7 +50,7 @@ def gzip_decompress(gzipped_string):
return f.read()


class FakeResponse(object):
class FakeResponse:
streaming = False

def __init__(self, content, headers=None, streaming=None):
Expand Down Expand Up @@ -255,7 +247,7 @@ class StreamingTest(SimpleTestCase):
int2byte(random.randint(0, 255)) for _ in range(500)
)
sequence = [b"a" * 500, b"b" * 200, b"a" * 300]
sequence_unicode = [u"a" * 500, u"é" * 200, u"a" * 300]
sequence_unicode = ["a" * 500, "é" * 200, "a" * 300]
request_factory = RequestFactory()

def setUp(self):
Expand Down
86 changes: 44 additions & 42 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals
from typing import Final

# Dummy text (aka Lorem ipsum) in Czech (credits: http://cs.blabot.net/) for testing compression
UTF8_LOREM_IPSUM_IN_CZECH = """S úsilí kdepak využívat současníků test pivo ovcím šimpanze. silnějšímu, tj. a
nezadal odeženou hlavu bránil do neúspěšné, silnějšímu, tj. zní ke svítí proběhl
lo podmínkách ústní i nepravděpodobné chytré. Výskyt laně postupu nežli aktivity
kousek výbavy prostředí pepřem, čím já jeden, 195. Patří tam moři propracovanoua
nahrubo míst orgánu pohroma svého epidemií stehny hlídá lidem geny o mnohdy, tea
chnologie já vynesl krása i zástupcům opačně letišti stavba. O provoz další opra
covaných vážilo z chemical staly, tam víkendu z plyne. Snad nádherným, stranu je
zdí pomezí pohřbeného epidemií mi u 540 ve volně kyčle nový mezi budov přirozené
a přáteli polarizovaný parazitů svahy. Vážit je den mamutí americký slovníky nad
plánoval důkaz, sloučení význam v požírají, ulice ale za všech blíž minulosti. o
U domů polonica kanále – čem já zahrada silou člověka EU touto začaly chodily mr
azy? Podepsala vláken postupně ve podél procházejí výjimky minimum, u naproti po
vinné Moravy vermontu domněnku odhadů střediskem k činu, můj avšak ty lokalizova
nému pravdou 570 něm zažijete podrobili odvětví nešlo. Dlouhou šimpanz vítejte g
enerací se brázdit doplňuje podobná té uměle dobrá. Tříkilometrové kategorií, by
480 a pokroku potom k čekala lokální. Kanadského, nálezů, jestli, něm poloostroa
vě, v Platón čeští duhový, nálezů z projev.\n\nObčany skotu kterých s ho stopami
pravdu ze desetiletí centimetrů jeví šest a místních důležitou, plná slonice nik
dy já spořádaně stavu naplaveninách prostředky profesorka. 1591 odstřihne, nebyl
y tento erupce odpočinout osluněné 1 v něm je temna popis malá sága týmem astero
idu z poznala standardních obeplutí názvy. Nejenže ke je hermeticky fyzici, dese
t kam migrační křídla úhrnem. Již ta učí šimpanzů stádech ať boky i přispívá int
ernetová k 500 ně se polohu teorii tady. Osmi po kampaň analyzovány jiná z alarm
ující další tlupa.\n\nKaždý 1921 připlouváte čemž pevnosti, hornina Moravy násle
y špatných, dnů ta. U ohňové v respirátorem spíš od závěru, má lidem 2005 již sv
aly, běžně matky i větry výška. Demenci globálního vyvraždila jí na překvapení s
lovácku bojem softwarových ty i strany půdy útěk svým s musí, 360° a vypráví šan
ci s narušení. Prací nepřešlapuje 3000 krásy cihlová, víkendu s a tu z zemském c
ítit větší. Vlna a uvádí kterou fatální divný společné – války zdravotním dané m
ířil. O nejpalčivější skoro rodilí o tato nemohou EU zvířat připomínalo činná pl
ná u rozbuška nechci tkví rozhovor roku široký. Toho dolní dopluli, či otevírá b
uňky mj. viry životní středověké klimatizační zachytit chřipkou.\n\nProvází změn
dravý ta svezení než takového vykreslují zemím níž ideálním pasivitou – plné mír
u neon strany membránou a jel, té stromů kameni ve bílý dobrovolníků v naději mě
ní o kuliček ta draci skoro ideální. Podobu vlny sérií tohle agrese restauraci z
a sněžilo dávných činila, nebyl ostrova s ředitelka ředitelka, nepřestaneme, pen
zionovaného k budoucnostzačne některé. Až horským zásad mé prokletých. Nobel dět
i zákonů emise. Klidné příčinou tradic plně vyvodíme doplňují a nejméně specific
kého tvrdí. Jí smrt při umělé objevováním.""" # type: str
# Dummy text (aka Lorem ipsum) in Czech (credits: http://cs.blabot.net/) for
# testing compression
UTF8_LOREM_IPSUM_IN_CZECH : Final[str] = (
"S úsilí kdepak využívat současníků test pivo ovcím šimpanze. silnějšímu, tj. a"
"nezadal odeženou hlavu bránil do neúspěšné, silnějšímu, tj. zní ke svítí proběhl"
"lo podmínkách ústní i nepravděpodobné chytré. Výskyt laně postupu nežli aktivity"
"kousek výbavy prostředí pepřem, čím já jeden, 195. Patří tam moři propracovanoua"
"nahrubo míst orgánu pohroma svého epidemií stehny hlídá lidem geny o mnohdy, tea"
"chnologie já vynesl krása i zástupcům opačně letišti stavba. O provoz další opra"
"covaných vážilo z chemical staly, tam víkendu z plyne. Snad nádherným, stranu je"
"zdí pomezí pohřbeného epidemií mi u 540 ve volně kyčle nový mezi budov přirozené"
"a přáteli polarizovaný parazitů svahy. Vážit je den mamutí americký slovníky nad"
"plánoval důkaz, sloučení význam v požírají, ulice ale za všech blíž minulosti. o"
"U domů polonica kanále – čem já zahrada silou člověka EU touto začaly chodily mr"
"azy? Podepsala vláken postupně ve podél procházejí výjimky minimum, u naproti po"
"vinné Moravy vermontu domněnku odhadů střediskem k činu, můj avšak ty lokalizova"
"nému pravdou 570 něm zažijete podrobili odvětví nešlo. Dlouhou šimpanz vítejte g"
"enerací se brázdit doplňuje podobná té uměle dobrá. Tříkilometrové kategorií, by"
"480 a pokroku potom k čekala lokální. Kanadského, nálezů, jestli, něm poloostroa"
"vě, v Platón čeští duhový, nálezů z projev.\n\nObčany skotu kterých s ho stopami"
"pravdu ze desetiletí centimetrů jeví šest a místních důležitou, plná slonice nik"
"dy já spořádaně stavu naplaveninách prostředky profesorka. 1591 odstřihne, nebyl"
"y tento erupce odpočinout osluněné 1 v něm je temna popis malá sága týmem astero"
"idu z poznala standardních obeplutí názvy. Nejenže ke je hermeticky fyzici, dese"
"t kam migrační křídla úhrnem. Již ta učí šimpanzů stádech ať boky i přispívá int"
"ernetová k 500 ně se polohu teorii tady. Osmi po kampaň analyzovány jiná z alarm"
"ující další tlupa.\n\nKaždý 1921 připlouváte čemž pevnosti, hornina Moravy násle"
"y špatných, dnů ta. U ohňové v respirátorem spíš od závěru, má lidem 2005 již sv"
"aly, běžně matky i větry výška. Demenci globálního vyvraždila jí na překvapení s"
"lovácku bojem softwarových ty i strany půdy útěk svým s musí, 360° a vypráví šan"
"ci s narušení. Prací nepřešlapuje 3000 krásy cihlová, víkendu s a tu z zemském c"
"ítit větší. Vlna a uvádí kterou fatální divný společné – války zdravotním dané m"
"ířil. O nejpalčivější skoro rodilí o tato nemohou EU zvířat připomínalo činná pl"
"ná u rozbuška nechci tkví rozhovor roku široký. Toho dolní dopluli, či otevírá b"
"uňky mj. viry životní středověké klimatizační zachytit chřipkou.\n\nProvází změn"
"dravý ta svezení než takového vykreslují zemím níž ideálním pasivitou – plné mír"
"u neon strany membránou a jel, té stromů kameni ve bílý dobrovolníků v naději mě"
"ní o kuliček ta draci skoro ideální. Podobu vlny sérií tohle agrese restauraci z"
"a sněžilo dávných činila, nebyl ostrova s ředitelka ředitelka, nepřestaneme, pen"
"zionovaného k budoucnostzačne některé. Až horským zásad mé prokletých. Nobel dět"
"i zákonů emise. Klidné příčinou tradic plně vyvodíme doplňují a nejméně specific"
"kého tvrdí. Jí smrt při umělé objevováním."
)
26 changes: 10 additions & 16 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,48 +1,42 @@
[tox]
envlist =
py{36,37,py36,py37}-django111-{brotlipy,Brotli}
py{36,37,py36,py37}-django20-{brotlipy,Brotli}
py{36,37,py36,py37}-django21-{brotlipy,Brotli}
py{36,37,38,py36,py37,py38}-django22-{brotlipy,Brotli}
py{36,37,38,39,py36,py37,py38,py39}-django{30,31}-{brotlipy,Brotli}
py{36,37,38,39,310,py36,py37,py38,py39,py310}-django32-{brotlipy,Brotli}
# Django 3.2 LTS
py{38,39,310,py38,py39,py310}-django32-{brotlipy,Brotli}
# Django 4.0/
py{38,39,310,py38,py39,py310}-django40-{brotlipy,Brotli}
# Django 4.1
py{38,39,310,311,py38,py39,py310}-django41-{brotlipy,Brotli}
# Django 4.2
py{38,39,310,311,312,py38,py39,py310}-django42-{brotlipy,Brotli}
# Django 5.0
py{310,311,312,py310}-django50-{brotlipy,Brotli}
# Django 5.1
py{310,311,312,py310}-django51-{brotlipy,Brotli}

skip_missing_interpreters = true
[testenv]
setenv =
PYTHONPATH = {toxinidir}
commands = pytest tests/
deps =
django111: Django>=1.11, <2.0
django20: Django>=2.0, < 2.1
django21: Django>=2.1, < 2.2
django22: Django>=2.2, < 3.0
django30: Django>=3.0, < 3.1
django31: Django>=3.1, < 3.2
django32: Django>=3.2, < 4.0
django40: Django>=4.0, < 4.1
django41: Django>=4.1, < 4.2
django42: Django>=4.2, < 4.3
django50: Django>=5.0, < 5.1
django51: Django>=5.1, < 5.2
pytest>=3.1
zstandard
brotlipy: brotlipy
Brotli: Brotli

[gh-actions]
python =
3.6: py36
3.7: py37
3.8: py38
3.9: py39
3.10: py310
3.11: py311
3.12: py312
pypy-3.6: pypy36
pypy-3.7: pypy37
pypy-3.8: pypy38
pypy-3.9: pypy39
pypy-3.10: pypy310