microdot 2.6.0__tar.gz → 2.6.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. {microdot-2.6.0/src/microdot.egg-info → microdot-2.6.2}/PKG-INFO +1 -1
  2. {microdot-2.6.0 → microdot-2.6.2}/docs/index.rst +2 -2
  3. {microdot-2.6.0 → microdot-2.6.2}/docs/users-guide/concurrency.rst +4 -4
  4. {microdot-2.6.0 → microdot-2.6.2}/docs/users-guide/responses.rst +1 -1
  5. {microdot-2.6.0 → microdot-2.6.2}/pyproject.toml +1 -1
  6. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/__init__.py +1 -1
  7. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/microdot.py +5 -1
  8. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/multipart.py +2 -1
  9. {microdot-2.6.0 → microdot-2.6.2/src/microdot.egg-info}/PKG-INFO +1 -1
  10. {microdot-2.6.0 → microdot-2.6.2}/src/microdot.egg-info/SOURCES.txt +0 -0
  11. {microdot-2.6.0 → microdot-2.6.2}/src/microdot.egg-info/dependency_links.txt +0 -0
  12. {microdot-2.6.0 → microdot-2.6.2}/src/microdot.egg-info/not-zip-safe +0 -0
  13. {microdot-2.6.0 → microdot-2.6.2}/src/microdot.egg-info/requires.txt +0 -0
  14. {microdot-2.6.0 → microdot-2.6.2}/src/microdot.egg-info/top_level.txt +0 -0
  15. {microdot-2.6.0 → microdot-2.6.2}/tests/test_multipart.py +14 -0
  16. {microdot-2.6.0 → microdot-2.6.2}/tests/test_response.py +9 -0
  17. {microdot-2.6.0 → microdot-2.6.2}/LICENSE +0 -0
  18. {microdot-2.6.0 → microdot-2.6.2}/MANIFEST.in +0 -0
  19. {microdot-2.6.0 → microdot-2.6.2}/README.md +0 -0
  20. {microdot-2.6.0 → microdot-2.6.2}/docs/Makefile +0 -0
  21. {microdot-2.6.0 → microdot-2.6.2}/docs/_static/css/custom.css +0 -0
  22. {microdot-2.6.0 → microdot-2.6.2}/docs/api/asgi.rst +0 -0
  23. {microdot-2.6.0 → microdot-2.6.2}/docs/api/auth.rst +0 -0
  24. {microdot-2.6.0 → microdot-2.6.2}/docs/api/cors.rst +0 -0
  25. {microdot-2.6.0 → microdot-2.6.2}/docs/api/csrf.rst +0 -0
  26. {microdot-2.6.0 → microdot-2.6.2}/docs/api/index.rst +0 -0
  27. {microdot-2.6.0 → microdot-2.6.2}/docs/api/jinja.rst +0 -0
  28. {microdot-2.6.0 → microdot-2.6.2}/docs/api/login.rst +0 -0
  29. {microdot-2.6.0 → microdot-2.6.2}/docs/api/microdot.rst +0 -0
  30. {microdot-2.6.0 → microdot-2.6.2}/docs/api/multipart.rst +0 -0
  31. {microdot-2.6.0 → microdot-2.6.2}/docs/api/sessions.rst +0 -0
  32. {microdot-2.6.0 → microdot-2.6.2}/docs/api/sse.rst +0 -0
  33. {microdot-2.6.0 → microdot-2.6.2}/docs/api/test_client.rst +0 -0
  34. {microdot-2.6.0 → microdot-2.6.2}/docs/api/utemplate.rst +0 -0
  35. {microdot-2.6.0 → microdot-2.6.2}/docs/api/websocket.rst +0 -0
  36. {microdot-2.6.0 → microdot-2.6.2}/docs/api/wsgi.rst +0 -0
  37. {microdot-2.6.0 → microdot-2.6.2}/docs/conf.py +0 -0
  38. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/auth.rst +0 -0
  39. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/cors.rst +0 -0
  40. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/csrf.rst +0 -0
  41. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/index.rst +0 -0
  42. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/login.rst +0 -0
  43. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/multipart.rst +0 -0
  44. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/production.rst +0 -0
  45. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/sessions.rst +0 -0
  46. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/sse.rst +0 -0
  47. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/templates.rst +0 -0
  48. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/test_client.rst +0 -0
  49. {microdot-2.6.0 → microdot-2.6.2}/docs/extensions/websocket.rst +0 -0
  50. {microdot-2.6.0 → microdot-2.6.2}/docs/implementation/freezing.rst +0 -0
  51. {microdot-2.6.0 → microdot-2.6.2}/docs/implementation/index.rst +0 -0
  52. {microdot-2.6.0 → microdot-2.6.2}/docs/implementation/migrating.rst +0 -0
  53. {microdot-2.6.0 → microdot-2.6.2}/docs/intro.rst +0 -0
  54. {microdot-2.6.0 → microdot-2.6.2}/docs/make.bat +0 -0
  55. {microdot-2.6.0 → microdot-2.6.2}/docs/users-guide/defining-routes.rst +0 -0
  56. {microdot-2.6.0 → microdot-2.6.2}/docs/users-guide/index.rst +0 -0
  57. {microdot-2.6.0 → microdot-2.6.2}/docs/users-guide/intro.rst +0 -0
  58. {microdot-2.6.0 → microdot-2.6.2}/docs/users-guide/request-object.rst +0 -0
  59. {microdot-2.6.0 → microdot-2.6.2}/setup.cfg +0 -0
  60. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/__init__.pyi +0 -0
  61. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/asgi.py +0 -0
  62. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/asgi.pyi +0 -0
  63. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/auth.py +0 -0
  64. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/auth.pyi +0 -0
  65. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/cors.py +0 -0
  66. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/cors.pyi +0 -0
  67. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/csrf.py +0 -0
  68. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/csrf.pyi +0 -0
  69. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/helpers.py +0 -0
  70. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/helpers.pyi +0 -0
  71. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/jinja.py +0 -0
  72. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/jinja.pyi +0 -0
  73. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/login.py +0 -0
  74. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/login.pyi +0 -0
  75. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/microdot.pyi +0 -0
  76. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/multipart.pyi +0 -0
  77. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/py.typed +0 -0
  78. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/session.py +0 -0
  79. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/session.pyi +0 -0
  80. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/sse.py +0 -0
  81. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/sse.pyi +0 -0
  82. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/test_client.py +0 -0
  83. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/test_client.pyi +0 -0
  84. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/utemplate.py +0 -0
  85. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/utemplate.pyi +0 -0
  86. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/websocket.py +0 -0
  87. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/websocket.pyi +0 -0
  88. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/wsgi.py +0 -0
  89. {microdot-2.6.0 → microdot-2.6.2}/src/microdot/wsgi.pyi +0 -0
  90. {microdot-2.6.0 → microdot-2.6.2}/tests/__init__.py +0 -0
  91. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.bin +0 -0
  92. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.css +0 -0
  93. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.gif +0 -0
  94. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.gz +0 -0
  95. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.html +0 -0
  96. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.jpg +0 -0
  97. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.js +0 -0
  98. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.json +0 -0
  99. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.png +0 -0
  100. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.txt +0 -0
  101. {microdot-2.6.0 → microdot-2.6.2}/tests/files/test.txt.gz +0 -0
  102. {microdot-2.6.0 → microdot-2.6.2}/tests/mock_socket.py +0 -0
  103. {microdot-2.6.0 → microdot-2.6.2}/tests/templates/hello.jinja.txt +0 -0
  104. {microdot-2.6.0 → microdot-2.6.2}/tests/templates/hello.utemplate.txt +0 -0
  105. {microdot-2.6.0 → microdot-2.6.2}/tests/templates/hello_utemplate_txt.py +0 -0
  106. {microdot-2.6.0 → microdot-2.6.2}/tests/test_asgi.py +0 -0
  107. {microdot-2.6.0 → microdot-2.6.2}/tests/test_auth.py +0 -0
  108. {microdot-2.6.0 → microdot-2.6.2}/tests/test_cors.py +0 -0
  109. {microdot-2.6.0 → microdot-2.6.2}/tests/test_csrf.py +0 -0
  110. {microdot-2.6.0 → microdot-2.6.2}/tests/test_end2end.py +0 -0
  111. {microdot-2.6.0 → microdot-2.6.2}/tests/test_jinja.py +0 -0
  112. {microdot-2.6.0 → microdot-2.6.2}/tests/test_login.py +0 -0
  113. {microdot-2.6.0 → microdot-2.6.2}/tests/test_microdot.py +0 -0
  114. {microdot-2.6.0 → microdot-2.6.2}/tests/test_multidict.py +0 -0
  115. {microdot-2.6.0 → microdot-2.6.2}/tests/test_request.py +0 -0
  116. {microdot-2.6.0 → microdot-2.6.2}/tests/test_session.py +0 -0
  117. {microdot-2.6.0 → microdot-2.6.2}/tests/test_sse.py +0 -0
  118. {microdot-2.6.0 → microdot-2.6.2}/tests/test_url_pattern.py +0 -0
  119. {microdot-2.6.0 → microdot-2.6.2}/tests/test_urlencode.py +0 -0
  120. {microdot-2.6.0 → microdot-2.6.2}/tests/test_utemplate.py +0 -0
  121. {microdot-2.6.0 → microdot-2.6.2}/tests/test_websocket.py +0 -0
  122. {microdot-2.6.0 → microdot-2.6.2}/tests/test_wsgi.py +0 -0
  123. {microdot-2.6.0 → microdot-2.6.2}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microdot
3
- Version: 2.6.0
3
+ Version: 2.6.2
4
4
  Summary: The impossibly small web framework for MicroPython
5
5
  Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/miguelgrinberg/microdot
@@ -9,8 +9,8 @@ Microdot
9
9
  *"The impossibly small web framework for Python and MicroPython"*
10
10
 
11
11
  Microdot is a minimalistic Python web framework inspired by
12
- `Flask <https://flask.palletsprojects.com/>`_. Given its size, it can run on
13
- systems with limited resources such as microcontrollers. Both standard Python
12
+ `Flask <https://flask.palletsprojects.com/>`_. Given its small size, it can run
13
+ on systems with limited resources such as microcontrollers. Both standard Python
14
14
  (CPython) and `MicroPython <https://micropython.org>`_ are supported.
15
15
 
16
16
  .. toctree::
@@ -8,7 +8,7 @@ that applications must be careful to prevent blocking in their handlers.
8
8
  ^^^^^^^^^^^^^^^^^^^^
9
9
 
10
10
  The recommendation for route handlers in Microdot is to use asynchronous
11
- functions, declared as ``async def``. Microdot executes these handler
11
+ functions, declared with ``async def``. Microdot executes these handler
12
12
  functions as native asynchronous tasks. The standard considerations for writing
13
13
  asynchronous code apply, and in particular blocking calls should be avoided to
14
14
  ensure the application runs smoothly and is always responsive.
@@ -24,9 +24,9 @@ When running on CPython, Microdot executes synchronous handlers in a
24
24
  `thread executor <https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor>`_,
25
25
  which uses a thread pool. The use of blocking or CPU intensive code in these
26
26
  handlers does not have such a negative effect on the application, because
27
- handlers do not run on the same thread as the asynchronous loop. On the other
28
- hand, the application will be affected by threading issues such as those caused
29
- by the Global Interpreter Lock.
27
+ the handlers run on a different threads than the one running the asynchronous
28
+ loop. On the other hand, the application will be affected by threading issues
29
+ such as those caused by the Global Interpreter Lock.
30
30
 
31
31
  Under MicroPython the situation is different. Most microcontroller boards
32
32
  do not have or have very limited threading support, so Microdot executes
@@ -196,5 +196,5 @@ Another option is to create a response object directly in the route function::
196
196
  Standard cookies do not offer sufficient privacy and security controls, so
197
197
  never store sensitive information in them unless you are adding additional
198
198
  protection mechanisms such as encryption or cryptographic signing. The
199
- :ref:`session <Maintaining Secure User Sessions>` extension implements signed
199
+ :ref:`session <Secure User Sessions>` extension implements signed
200
200
  cookies that prevent tampering by malicious actors.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "microdot"
3
- version = "2.6.0"
3
+ version = "2.6.2"
4
4
  authors = [
5
5
  { name = "Miguel Grinberg", email = "miguel.grinberg@gmail.com" },
6
6
  ]
@@ -1,4 +1,4 @@
1
1
  from microdot.microdot import Microdot, Request, Response, abort, redirect, \
2
2
  send_file, URLPattern, AsyncBytesIO, iscoroutine # noqa: F401
3
3
 
4
- __version__ = '2.6.0'
4
+ __version__ = '2.6.2'
@@ -611,6 +611,8 @@ class Response:
611
611
  :param http_only: The cookie's ``HttpOnly`` flag.
612
612
  :param partitioned: Whether the cookie is partitioned.
613
613
  """
614
+ if ';' in value:
615
+ raise ValueError('invalid cookie value')
614
616
  http_cookie = '{cookie}={value}'.format(cookie=cookie, value=value)
615
617
  if path:
616
618
  http_cookie += '; Path=' + path
@@ -630,6 +632,8 @@ class Response:
630
632
  http_cookie += '; HttpOnly'
631
633
  if partitioned:
632
634
  http_cookie += '; Partitioned'
635
+ if '\r' in http_cookie or '\n' in http_cookie:
636
+ raise ValueError('invalid cookie')
633
637
  if 'Set-Cookie' in self.headers:
634
638
  self.headers['Set-Cookie'].append(http_cookie)
635
639
  else:
@@ -762,7 +766,7 @@ class Response:
762
766
  :param status_code: The 3xx status code to use for the redirect. The
763
767
  default is 302.
764
768
  """
765
- if '\x0d' in location or '\x0a' in location:
769
+ if '\r' in location or '\n' in location:
766
770
  raise ValueError('invalid redirect URL')
767
771
  return cls(status_code=status_code, headers={'Location': location})
768
772
 
@@ -40,8 +40,9 @@ class FormDataIter:
40
40
  def __init__(self, request):
41
41
  self.request = request
42
42
  self.buffer = None
43
+ content_type = request.content_type or ''
43
44
  try:
44
- mimetype, boundary = request.content_type.rsplit('; boundary=', 1)
45
+ mimetype, boundary = content_type.rsplit('; boundary=', 1)
45
46
  except ValueError:
46
47
  return # not a multipart request
47
48
  if mimetype.split(';', 1)[0] == \
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microdot
3
- Version: 2.6.0
3
+ Version: 2.6.2
4
4
  Summary: The impossibly small web framework for MicroPython
5
5
  Author-email: Miguel Grinberg <miguel.grinberg@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/miguelgrinberg/microdot
@@ -172,6 +172,20 @@ class TestMultipart(unittest.TestCase):
172
172
  self.assertEqual(res.status_code, 200)
173
173
  self.assertEqual(res.text, 'None')
174
174
 
175
+ def test_no_content_type(self):
176
+ app = Microdot()
177
+
178
+ @app.route('/async', methods=['GET', 'POST'])
179
+ @with_form_data
180
+ async def async_route(req):
181
+ return str(req.form)
182
+
183
+ client = TestClient(app)
184
+
185
+ res = self._run(client.get('/async'))
186
+ self.assertEqual(res.status_code, 200)
187
+ self.assertEqual(res.text, 'None')
188
+
175
189
  def test_upload_iterator(self):
176
190
  app = Microdot()
177
191
 
@@ -194,6 +194,15 @@ class TestResponse(unittest.TestCase):
194
194
  secure=True, http_only=True)
195
195
  res.delete_cookie('foo8', http_only=True)
196
196
  res.delete_cookie('foo9', path='/s')
197
+ with self.assertRaises(ValueError):
198
+ res.set_cookie('foo1', 'bar1\r\nSet-Cookie: foo2=bar2')
199
+ with self.assertRaises(ValueError):
200
+ res.set_cookie('foo1', 'bar1',
201
+ domain='example.com\r\nSet-Cookie: foo2=bar2')
202
+ with self.assertRaises(ValueError):
203
+ res.set_cookie('foo1', 'bar1', path='/\r\nSet-Cookie: foo2=bar2')
204
+ with self.assertRaises(ValueError):
205
+ res.set_cookie('foo10', 'x;y', path='/')
197
206
  self.assertEqual(res.headers, {'Set-Cookie': [
198
207
  'foo1=bar1',
199
208
  'foo2=bar2; Path=/; Partitioned',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes