This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2014年07月01日 03:15 by rschoon, last changed 2022年04月11日 14:58 by admin.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| wsgiref-empty-byte.patch | rschoon, 2014年07月01日 03:15 | review | ||
| wsgiref-empty-byte-2.patch | rschoon, 2014年07月02日 23:00 | hopefully not wrongheaded this time | review | |
| wsgiref-empty-byte-3.patch | rschoon, 2014年07月02日 23:53 | add another test | review | |
| Messages (5) | |||
|---|---|---|---|
| msg222005 - (view) | Author: Robin Schoonover (rschoon) * | Date: 2014年07月01日 03:15 | |
Consider this paragraph of PEP3333, referring to headers obtained via start_response, emphasis mine: Instead, it must store them for the server or gateway to transmit only after the first iteration of the application return value that yields a *non-empty bytestring*, or upon the application's first invocation of the write() callable. This means that an WSGI app such as this should be valid, because the yielded bytes pre-start_response are empty: def application(environ, start_response): yield b'' start_response("200 OK", [("Content-Type", "text/plain")]) yield b'Hello, World.\n' However, in wsgiref's simple server, this fails: Traceback (most recent call last): File "/usr/local/lib/python3.4/wsgiref/handlers.py", line 180, in finish_response self.write(data) File "/usr/local/lib/python3.4/wsgiref/handlers.py", line 269, in write raise AssertionError("write() before start_response()") AssertionError: write() before start_response() |
|||
| msg222117 - (view) | Author: PJ Eby (pje) * (Python committer) | Date: 2014年07月02日 18:57 | |
Please see this paragraph of the spec (my emphasis added): (Note: the application must invoke the start_response() callable **before the iterable yields its first body string**, so that the server can send the headers before any body content. However, this invocation may be performed by the iterable's first iteration, so servers must not assume that start_response() has been called before they begin iterating over the iterable.) The paragraph you quoted says that start_response() has to buffer headers until a non-empty string is yielded. It does *not* say that strings can be yielded prior to calling start_response(). Indeed, the paragraph I quote above states the opposite: you can't call start_response() before yielding your first body string (whether empty or not). This is a known issue with the spec, but it's an issue with the *spec*, not the implementation. WSGI 1.0 is known to be unusable as a truly async API, for this and other reasons. |
|||
| msg222135 - (view) | Author: Robin Schoonover (rschoon) * | Date: 2014年07月02日 21:54 | |
Fair enough, I misled myself.
However, and I feel like I'm getting really picky here, but it still doesn't fulfill the paragraph I quoted:
def application(environ, start_response):
start_response('200 OK',
[('Content-type', 'text/plain')])
yield b''
try:
# produce an exception tuple, so we can re-call s_r
raise RuntimeError
except RuntimeError:
# Headers shouldn't have been sent, but they were
# so this will throw:
start_response('200 OK',
[('Content-type', 'text/plain')],
sys.exc_info())
yield b'error data or whatever'
But if async support a foregone conclusion anyway, is it worth bothering complying with that odd requirement?
|
|||
| msg222138 - (view) | Author: PJ Eby (pje) * (Python committer) | Date: 2014年07月02日 22:26 | |
You're right, it shouldn't send the headers until a non-empty string occurs. I don't see any problem with treating it as a bug, and fixing it. Your patch will also allow non-compliant behavior, though. It seems to me it would be better to fix the logic in write() to not call send_headers() if len(data)==0. That way, it will still error with "write() before start_response()" in the non-compliant case, but fix the compliance error. Feel free to reopen/retitle this issue for that. |
|||
| msg222143 - (view) | Author: Robin Schoonover (rschoon) * | Date: 2014年07月02日 23:00 | |
I agree, the current patch is too permissive. Both a server I wrote a while ago, and most other "complaint" servers deal with the problem the exact same way as that patch, and that extra permissiveness led to my misinterpretation when analyzing why I had made that original change. In any case, I've attached an updated patch. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:58:05 | admin | set | github: 66089 |
| 2016年05月06日 11:45:50 | berker.peksag | set | nosy:
+ berker.peksag stage: patch review versions: + Python 2.7, Python 3.5, Python 3.6 |
| 2014年07月02日 23:53:11 | rschoon | set | files: + wsgiref-empty-byte-3.patch |
| 2014年07月02日 23:00:36 | rschoon | set | status: closed -> open files: + wsgiref-empty-byte-2.patch title: wsgiref.simple_server doesn't accept empty bytes before start_response is called -> wsgiref.simple_server sends headers on empty bytes messages: + msg222143 resolution: not a bug -> |
| 2014年07月02日 22:26:54 | pje | set | messages: + msg222138 |
| 2014年07月02日 21:54:21 | rschoon | set | messages: + msg222135 |
| 2014年07月02日 18:57:06 | pje | set | status: open -> closed resolution: not a bug messages: + msg222117 |
| 2014年07月01日 03:15:44 | rschoon | set | files:
+ wsgiref-empty-byte.patch keywords: + patch |
| 2014年07月01日 03:15:10 | rschoon | create | |