Show More
@@ -15,7 +15,6 b' from .common import (' | |||
|
15 | 15 | ErrorResponse, |
|
16 | 16 | HTTP_BAD_REQUEST, |
|
17 | 17 | HTTP_NOT_FOUND, |
|
18 | HTTP_NOT_MODIFIED, | |
|
19 | 18 | HTTP_OK, |
|
20 | 19 | HTTP_SERVER_ERROR, |
|
21 | 20 | cspvalues, |
@@ -391,7 +390,10 b' class hgweb(object):' | |||
|
391 | 390 | if rctx.configbool('web', 'cache') and not rctx.nonce: |
|
392 | 391 | tag = 'W/"%d"' % self.mtime |
|
393 | 392 | if req.headers.get('If-None-Match') == tag: |
|
394 | raise ErrorResponse(HTTP_NOT_MODIFIED) | |
|
393 | res.status = '304 Not Modified' | |
|
394 | # Response body not allowed on 304. | |
|
395 | res.setbodybytes('') | |
|
396 | return res.sendresponse() | |
|
395 | 397 | |
|
396 | 398 | wsgireq.headers.append((r'ETag', pycompat.sysstr(tag))) |
|
397 | 399 | res.headers['ETag'] = tag |
@@ -426,9 +428,6 b' class hgweb(object):' | |||
|
426 | 428 | return tmpl('error', error=pycompat.bytestr(inst)) |
|
427 | 429 | except ErrorResponse as inst: |
|
428 | 430 | wsgireq.respond(inst, ctype) |
|
429 | if inst.code == HTTP_NOT_MODIFIED: | |
|
430 | # Not allowed to return a body on a 304 | |
|
431 | return [''] | |
|
432 | 431 | return tmpl('error', error=pycompat.bytestr(inst)) |
|
433 | 432 | |
|
434 | 433 | def check_perm(self, rctx, req, op): |
@@ -15,7 +15,6 b' import wsgiref.headers as wsgiheaders' | |||
|
15 | 15 | |
|
16 | 16 | from .common import ( |
|
17 | 17 | ErrorResponse, |
|
18 | HTTP_NOT_MODIFIED, | |
|
19 | 18 | statusmessage, |
|
20 | 19 | ) |
|
21 | 20 | |
@@ -361,7 +360,10 b' class wsgiresponse(object):' | |||
|
361 | 360 | raise error.ProgrammingError('cannot define body multiple times') |
|
362 | 361 | |
|
363 | 362 | def setbodybytes(self, b): |
|
364 |
"""Define the response body as static bytes. |
|
|
363 | """Define the response body as static bytes. | |
|
364 | ||
|
365 | The empty string signals that there is no response body. | |
|
366 | """ | |
|
365 | 367 | self._verifybody() |
|
366 | 368 | self._bodybytes = b |
|
367 | 369 | self.headers['Content-Length'] = '%d' % len(b) |
@@ -408,6 +410,35 b' class wsgiresponse(object):' | |||
|
408 | 410 | and not self._bodywillwrite): |
|
409 | 411 | raise error.ProgrammingError('response body not defined') |
|
410 | 412 | |
|
413 | # RFC 7232 Section 4.1 states that a 304 MUST generate one of | |
|
414 | # {Cache-Control, Content-Location, Date, ETag, Expires, Vary} | |
|
415 | # and SHOULD NOT generate other headers unless they could be used | |
|
416 | # to guide cache updates. Furthermore, RFC 7230 Section 3.3.2 | |
|
417 | # states that no response body can be issued. Content-Length can | |
|
418 | # be sent. But if it is present, it should be the size of the response | |
|
419 | # that wasn't transferred. | |
|
420 | if self.status.startswith('304 '): | |
|
421 | # setbodybytes('') will set C-L to 0. This doesn't conform with the | |
|
422 | # spec. So remove it. | |
|
423 | if self.headers.get('Content-Length') == '0': | |
|
424 | del self.headers['Content-Length'] | |
|
425 | ||
|
426 | # Strictly speaking, this is too strict. But until it causes | |
|
427 | # problems, let's be strict. | |
|
428 | badheaders = {k for k in self.headers.keys() | |
|
429 | if k.lower() not in ('date', 'etag', 'expires', | |
|
430 | 'cache-control', | |
|
431 | 'content-location', | |
|
432 | 'vary')} | |
|
433 | if badheaders: | |
|
434 | raise error.ProgrammingError( | |
|
435 | 'illegal header on 304 response: %s' % | |
|
436 | ', '.join(sorted(badheaders))) | |
|
437 | ||
|
438 | if self._bodygen is not None or self._bodywillwrite: | |
|
439 | raise error.ProgrammingError("must use setbodybytes('') with " | |
|
440 | "304 responses") | |
|
441 | ||
|
411 | 442 | # Various HTTP clients (notably httplib) won't read the HTTP response |
|
412 | 443 | # until the HTTP request has been sent in full. If servers (us) send a |
|
413 | 444 | # response before the HTTP request has been fully sent, the connection |
@@ -539,13 +570,6 b' class wsgirequest(object):' | |||
|
539 | 570 | |
|
540 | 571 | if isinstance(status, ErrorResponse): |
|
541 | 572 | self.headers.extend(status.headers) |
|
542 | if status.code == HTTP_NOT_MODIFIED: | |
|
543 | # RFC 2616 Section 10.3.5: 304 Not Modified has cases where | |
|
544 | # it MUST NOT include any headers other than these and no | |
|
545 | # body | |
|
546 | self.headers = [(k, v) for (k, v) in self.headers if | |
|
547 | k in ('Date', 'ETag', 'Expires', | |
|
548 | 'Cache-Control', 'Vary')] | |
|
549 | 573 | status = statusmessage(status.code, pycompat.bytestr(status)) |
|
550 | 574 | elif status == 200: |
|
551 | 575 | status = '200 Script output follows' |
General Comments 0
You need to be logged in to leave comments.
Login now