Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add max_receive_message_length param #25

Merged
merged 4 commits into from
Dec 13, 2020
Merged
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
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ This new version comes with flexibility to use any prefix for the server URLs an

If you want to use the server and clients of v5, then use the [0.0.1](https://github.com/verloop/twirpy/releases/tag/0.0.1) release.

### Message Body Length

Currently, message body length limit is set to 100kb, you can override this by passing `max_receive_message_length` to `TwirpASGIApp` constructor.

```python
# this sets max message length to be 10 bytes
app = TwirpASGIApp(max_receive_message_length=10)

```

## Support and community
Python: [#twirp](https://python-community.slack.com/messages/twirp). Join Python community slack [here](https://pythoncommunity.herokuapp.com)

Expand Down
24 changes: 24 additions & 0 deletions twirp/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ async def __call__(self, scope, receive, send):

endpoint = self._get_endpoint(scope['path'])
headers = {k.decode('utf-8'): v.decode('utf-8') for (k,v) in scope['headers']}
self.validate_content_length(headers=headers)
encoder, decoder = self._get_encoder_decoder(endpoint, headers)

# add headers from request into context
Expand Down Expand Up @@ -157,4 +158,27 @@ async def _recv_all(self, receive):
message = await receive()
body += message.get('body', b'')
more_body = message.get('more_body', False)

# the body length exceeded than the size set, raise a valid exception
# so that proper error is returned to the client
if self._max_receive_message_length < len(body):
raise exceptions.TwirpServerException(
code=errors.Errors.InvalidArgument,
message=F"message body exceeds the specified length of {self._max_receive_message_length} bytes"
)

return body

# we will check content-length header value and make sure it is
# below the limit set
def validate_content_length(self, headers):
try:
content_length = int(headers.get('content-length'))
except (ValueError, TypeError):
return

if self._max_receive_message_length < content_length:
raise exceptions.TwirpServerException(
code=errors.Errors.InvalidArgument,
message=F"message body exceeds the specified length of {self._max_receive_message_length} bytes"
)
3 changes: 2 additions & 1 deletion twirp/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@


class TwirpBaseApp(object):
def __init__(self, *middlewares, hook=None, prefix="", ctx_class=None):
def __init__(self, *middlewares, hook=None, prefix="", max_receive_message_length=1024*100*100, ctx_class=None):
self._prefix = prefix
self._services = {}
self._max_receive_message_length = max_receive_message_length
if ctx_class is None:
ctx_class = context.Context
assert issubclass(ctx_class, context.Context)
Expand Down