The Python 3 WSGI behavior is that the environ dict should be full of
unicodes. We previously tried Too Hard here, so we unwind that bit of porting.
Also add some bytesurl() encodes on status and headers.
test-clone-cgi.t now passes.
pulkit | |
indygreg |
hg-reviewers |
The Python 3 WSGI behavior is that the environ dict should be full of
unicodes. We previously tried Too Hard here, so we unwind that bit of porting.
Also add some bytesurl() encodes on status and headers.
test-clone-cgi.t now passes.
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
Path | Packages | |||
---|---|---|---|---|
M | contrib/python3-whitelist (1 line) | |||
M | mercurial/hgweb/wsgicgi.py (13 lines) |
Status | Author | Revision | |
---|---|---|---|
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 | ||
Closed | durin42 |
test-changelog-exec.t | test-changelog-exec.t | ||||
test-check-commit.t | test-check-commit.t | ||||
test-check-execute.t | test-check-execute.t | ||||
test-check-module-imports.t | test-check-module-imports.t | ||||
test-check-pyflakes.t | test-check-pyflakes.t | ||||
test-check-pylint.t | test-check-pylint.t | ||||
test-check-shbang.t | test-check-shbang.t | ||||
test-children.t | test-children.t | ||||
test-clone-cgi.t | |||||
test-clone-pull-corruption.t | test-clone-pull-corruption.t | ||||
test-clone-r.t | test-clone-r.t | ||||
test-clone-update-order.t | test-clone-update-order.t | ||||
test-command-template.t | test-command-template.t | ||||
test-commit-amend.t | test-commit-amend.t | ||||
test-commit-interactive.t | test-commit-interactive.t | ||||
test-commit-multiple.t | test-commit-multiple.t | ||||
test-commit-unresolved.t | test-commit-unresolved.t |
# hgweb/wsgicgi.py - CGI->WSGI translator | # hgweb/wsgicgi.py - CGI->WSGI translator | ||||
# | # | ||||
# Copyright 2006 Eric Hopper <hopper@omnifarious.org> | # Copyright 2006 Eric Hopper <hopper@omnifarious.org> | ||||
# | # | ||||
# This software may be used and distributed according to the terms of the | # This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | # GNU General Public License version 2 or any later version. | ||||
# | # | ||||
# This was originally copied from the public domain code at | # This was originally copied from the public domain code at | ||||
# http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side | # http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side | ||||
from __future__ import absolute_import | from __future__ import absolute_import | ||||
import os | |||||
from .. import ( | from .. import ( | ||||
encoding, | pycompat, | ||||
) | ) | ||||
from ..utils import ( | from ..utils import ( | ||||
procutil, | procutil, | ||||
) | ) | ||||
from . import ( | from . import ( | ||||
common, | common, | ||||
) | ) | ||||
def launch(application): | def launch(application): | ||||
procutil.setbinary(procutil.stdin) | procutil.setbinary(procutil.stdin) | ||||
procutil.setbinary(procutil.stdout) | procutil.setbinary(procutil.stdout) | ||||
environ = dict(encoding.environ.iteritems()) | environ = dict(os.environ.iteritems()) # re-exports | ||||
environ.setdefault(r'PATH_INFO', '') | environ.setdefault(r'PATH_INFO', '') | ||||
if environ.get(r'SERVER_SOFTWARE', r'').startswith(r'Microsoft-IIS'): | if environ.get(r'SERVER_SOFTWARE', r'').startswith(r'Microsoft-IIS'): | ||||
# IIS includes script_name in PATH_INFO | # IIS includes script_name in PATH_INFO | ||||
scriptname = environ[r'SCRIPT_NAME'] | scriptname = environ[r'SCRIPT_NAME'] | ||||
if environ[r'PATH_INFO'].startswith(scriptname): | if environ[r'PATH_INFO'].startswith(scriptname): | ||||
environ[r'PATH_INFO'] = environ[r'PATH_INFO'][len(scriptname):] | environ[r'PATH_INFO'] = environ[r'PATH_INFO'][len(scriptname):] | ||||
stdin = procutil.stdin | stdin = procutil.stdin | ||||
def write(data): | def write(data): | ||||
if not headers_set: | if not headers_set: | ||||
raise AssertionError("write() before start_response()") | raise AssertionError("write() before start_response()") | ||||
elif not headers_sent: | elif not headers_sent: | ||||
# Before the first output, send the stored headers | # Before the first output, send the stored headers | ||||
status, response_headers = headers_sent[:] = headers_set | status, response_headers = headers_sent[:] = headers_set | ||||
out.write('Status: %s\r\n' % status) | out.write('Status: %s\r\n' % pycompat.bytesurl(status)) | ||||
for header in response_headers: | for hk, hv in response_headers: | ||||
out.write('%s: %s\r\n' % header) | out.write('%s: %s\r\n' % (pycompat.bytesurl(hk), | ||||
pycompat.bytesurl(hv))) | |||||
out.write('\r\n') | out.write('\r\n') | ||||
out.write(data) | out.write(data) | ||||
out.flush() | out.flush() | ||||
def start_response(status, response_headers, exc_info=None): | def start_response(status, response_headers, exc_info=None): | ||||
if exc_info: | if exc_info: | ||||
try: | try: |