How to fix [ERROR] [2699022] wsgiHandler pApp->start_response() return NULL?

只谈情不闲聊 提交于 2020-01-16 19:05:05

问题


I'm setting up a new server "LiteSpeed" , I am using Django 2.1.7 web framework every thing was good until i uploaded from admin a photo with a name contains Arabic letters

this image gives me an error

"The server encountered an unexpected condition which prevented it from fulfilling the request." so i review the server log and found that link throws an error

2019-06-09 00:26:17.429165 [ERROR] [2699022] wsgiHandler pApp->start_response() return NULL.
Traceback (most recent call last):
  File "/home/qassimchalets/virtualenv/Py/3.7/lib/python3.7/site-packages/django/core/handlers/wsgi.py", line 139, in __call__
    set_script_prefix(get_script_name(environ))
  File "/home/qassimchalets/virtualenv/Py/3.7/lib/python3.7/site-packages/django/core/handlers/wsgi.py", line 179, in get_script_name
    script_url = get_bytes_from_wsgi(environ, 'SCRIPT_URL', '') or get_bytes_from_wsgi(environ, 'REDIRECT_URL', '')
  File "/home/qassimchalets/virtualenv/Py/3.7/lib/python3.7/site-packages/django/core/handlers/wsgi.py", line 204, in get_bytes_from_wsgi
    return value.encode('iso-8859-1')
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 23-26: ordinal not in range(256)

i have searched a lot with no good result so i changed this line return value.encode('iso-8859-1') with return value.encode('utf-8') in the core of the framework it works now for the link of the photo and other photos

I don't know if it will affect another things , as I changed in django handler core without any idea what this is really doing

class WSGIRequest(HttpRequest):
    def __init__(self, environ):
        script_name = get_script_name(environ)
        # If PATH_INFO is empty (e.g. accessing the SCRIPT_NAME URL without a
        # trailing slash), operate as if '/' was requested.
        path_info = get_path_info(environ) or '/'
        self.environ = environ
        self.path_info = path_info
        # be careful to only replace the first slash in the path because of
        # http://test/something and http://test//something being different as
        # stated in https://www.ietf.org/rfc/rfc2396.txt
        self.path = '%s/%s' % (script_name.rstrip('/'),
                               path_info.replace('/', '', 1))
        self.META = environ
        self.META['PATH_INFO'] = path_info
        self.META['SCRIPT_NAME'] = script_name
        self.method = environ['REQUEST_METHOD'].upper()
        self.content_type, self.content_params = cgi.parse_header(environ.get('CONTENT_TYPE', ''))
        if 'charset' in self.content_params:
            try:
                codecs.lookup(self.content_params['charset'])
            except LookupError:
                pass
            else:
                self.encoding = self.content_params['charset']
        self._post_parse_error = False
        try:
            content_length = int(environ.get('CONTENT_LENGTH'))
        except (ValueError, TypeError):
            content_length = 0
        self._stream = LimitedStream(self.environ['wsgi.input'], content_length)
        self._read_started = False
        self.resolver_match = None

    def _get_scheme(self):
        return self.environ.get('wsgi.url_scheme')

    @cached_property
    def GET(self):
        # The WSGI spec says 'QUERY_STRING' may be absent.
        raw_query_string = get_bytes_from_wsgi(self.environ, 'QUERY_STRING', '')
        return QueryDict(raw_query_string, encoding=self._encoding)

    def _get_post(self):
        if not hasattr(self, '_post'):
            self._load_post_and_files()
        return self._post

    def _set_post(self, post):
        self._post = post

    @cached_property
    def COOKIES(self):
        raw_cookie = get_str_from_wsgi(self.environ, 'HTTP_COOKIE', '')
        return parse_cookie(raw_cookie)

    @property
    def FILES(self):
        if not hasattr(self, '_files'):
            self._load_post_and_files()
        return self._files

    POST = property(_get_post, _set_post)


class WSGIHandler(base.BaseHandler):
    request_class = WSGIRequest

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.load_middleware()

    def __call__(self, environ, start_response):
        set_script_prefix(get_script_name(environ))
        signals.request_started.send(sender=self.__class__, environ=environ)
        request = self.request_class(environ)
        response = self.get_response(request)

        response._handler_class = self.__class__

        status = '%d %s' % (response.status_code, response.reason_phrase)
        response_headers = list(response.items())
        for c in response.cookies.values():
            response_headers.append(('Set-Cookie', c.output(header='')))
        start_response(status, response_headers)
        if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'):
            response = environ['wsgi.file_wrapper'](response.file_to_stream)
        return response


def get_path_info(environ):
    """Return the HTTP request's PATH_INFO as a string."""
    path_info = get_bytes_from_wsgi(environ, 'PATH_INFO', '/')

    return repercent_broken_unicode(path_info).decode()


def get_script_name(environ):
    """
    Return the equivalent of the HTTP request's SCRIPT_NAME environment
    variable. If Apache mod_rewrite is used, return what would have been
    the script name prior to any rewriting (so it's the script name as seen
    from the client's perspective), unless the FORCE_SCRIPT_NAME setting is
    set (to anything).
    """
    if settings.FORCE_SCRIPT_NAME is not None:
        return settings.FORCE_SCRIPT_NAME

    # If Apache's mod_rewrite had a whack at the URL, Apache set either
    # SCRIPT_URL or REDIRECT_URL to the full resource URL before applying any
    # rewrites. Unfortunately not every Web server (lighttpd!) passes this
    # information through all the time, so FORCE_SCRIPT_NAME, above, is still
    # needed.
    script_url = get_bytes_from_wsgi(environ, 'SCRIPT_URL', '') or get_bytes_from_wsgi(environ, 'REDIRECT_URL', '')

    if script_url:
        if b'//' in script_url:
            # mod_wsgi squashes multiple successive slashes in PATH_INFO,
            # do the same with script_url before manipulating paths (#17133).
            script_url = _slashes_re.sub(b'/', script_url)
        path_info = get_bytes_from_wsgi(environ, 'PATH_INFO', '')
        script_name = script_url[:-len(path_info)] if path_info else script_url
    else:
        script_name = get_bytes_from_wsgi(environ, 'SCRIPT_NAME', '')

    return script_name.decode()


def get_bytes_from_wsgi(environ, key, default):
    """
    Get a value from the WSGI environ dictionary as bytes.

    key and default should be strings.
    """
    value = environ.get(key, default)
    # Non-ASCII values in the WSGI environ are arbitrarily decoded with
    # ISO-8859-1. This is wrong for Django websites where UTF-8 is the default.
    # Re-encode to recover the original bytestring.
    return value.encode('iso-8859-1')

I am really afraid of any non-expected behavior based on this change

just give me a good solution for that error as i think my solution will get more errors in future


回答1:


just used a technique to ensure that the file name or image name will be not containing any characters that will cause the problem

class City(models.Model):
    name = models.CharField(max_length=100, verbose_name=_("City Name"),
                            validators=[RegexValidator(r'^[\u0621-\u064A\u0660-\u0669]+$')])
    city_image = models.ImageField(upload_to='city/images/', blank=False, null=True, verbose_name=_("City Image"))

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        name = self.city_image.name
        extension = name.split('.')[-1]
        for char in name:
            if char not in 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.':
                self.city_image.name = 'a' + '.' + extension
                break
        instance = super(City, self).save(force_insert=False, force_update=False, using=None,
                                          update_fields=None)


来源:https://stackoverflow.com/questions/56511426/how-to-fix-error-2699022-wsgihandler-papp-start-response-return-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!