Skip to content

gh-66077: Fix blocking reads from wsgi.input in wsgiref.simple_server#148803

Open
bangseongbeom wants to merge 1 commit intopython:mainfrom
bangseongbeom:wsgi-input-blocking-reads
Open

gh-66077: Fix blocking reads from wsgi.input in wsgiref.simple_server#148803
bangseongbeom wants to merge 1 commit intopython:mainfrom
bangseongbeom:wsgi-input-blocking-reads

Conversation

@bangseongbeom
Copy link
Copy Markdown
Contributor

@bangseongbeom bangseongbeom commented Apr 20, 2026

The existing implementation of wsgiref.simple_server does not properly comply with the requirements in PEP 3333:

The server is not required to read past the client’s specified Content-Length, and should simulate an end-of-file condition if the application attempts to read past that point. The application should not attempt to read more data than is specified by the CONTENT_LENGTH variable.

A server should allow read() to be called without an argument, and return the remainder of the client’s input stream.

A server should return empty bytestrings from any attempt to read from an empty or exhausted input stream.

To satisfy these requirements, this PR introduces InputWrapper. This class is instantiated when the request includes a Content-Length, and is responsible for treating Content-Length as the end of the input stream.

In addition, since PEP 3333 allows read() to be called without an argument, I updated wsgiref.validate and the related tests accordingly.

I also added a few tests, though I'm not completely sure they were added correctly. I'd appreciate it if you could take a look.


📚 Documentation preview 📚: https://cpython-previews--148803.org.readthedocs.build/

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates wsgiref.simple_server to comply with PEP 3333’s wsgi.input semantics by preventing blocking reads past the request body, and aligns wsgiref.validate with the spec allowing read() to be called with no arguments.

Changes:

  • Add an input-stream wrapper in wsgiref.simple_server that enforces Content-Length as an EOF boundary for wsgi.input.
  • Update wsgiref.validate to allow wsgi.input.read() with zero or one argument, and adjust tests accordingly.
  • Document the new WSGIRequestHandler.get_stdin() hook and add integration tests covering read, readline, readlines, and iteration behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
Misc/NEWS.d/next/Library/2026-04-21-01-58-47.gh-issue-66077.dvcX2i.rst Adds a NEWS entry describing the wsgi.input blocking fix.
Lib/wsgiref/validate.py Updates validator to permit wsgi.input.read() without arguments.
Lib/wsgiref/simple_server.py Introduces InputWrapper and routes wsgi.input through get_stdin() when Content-Length is present.
Lib/test/test_wsgiref.py Adds/updates integration tests to cover the new wsgi.input behaviors.
Doc/library/wsgiref.rst Documents WSGIRequestHandler.get_stdin() behavior and override point.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +143 to +148
def get_stdin(self):
length = self.headers.get('content-length')
if length:
return InputWrapper(self.rfile, int(length))
else:
return self.rfile
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to RFC 9110, Content-Length must be an integer number. Do we need to handle cases where it is not an integer as an exception?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants