You might be missing the correct LOCALE settings for Apache - I think the Django docs cover this.
On Fri, Dec 18, 2015 at 8:27 PM, <[email protected]> wrote: > I am working on a project which uses ThreadedComments in a couple of apps > (Mezzanine Blog and a discussion forum). All was working fine in the > development and production environment but from one day to the next posting > a comment raised an Internal Server Error (500). > > My setup: Mezzanine 4.01, Django 1.8.5, Python 2.7.6. The production > environment is a Ubuntu 14.04 server, Apache webserver. Mezzanine is > deployed using mod_wsgi-express. Mezzanine is set up using "German" as > language. > > The error log created by the server gives me the following: > > Traceback (most recent call last): > [Thu Dec 17 21:08:23.317452 2015] [wsgi:error] [pid 30806:tid > 140269963933440] [remote 95.90.251.8:24357] File > "/home/chris/IT/Portal/veportal/local/lib/python2.7/site-packages/mod_wsgi-4.4.15-py2.7-linux-x86_64.egg/mod_wsgi/server/__init__.py" > , line 1346, in handle_request > [Thu Dec 17 21:08:23.317902 2015] [wsgi:error] [pid 30806:tid > 140269963933440] [remote 95.90.251.8:24357] return self.application( > environ, start_response) > [Thu Dec 17 21:08:23.317919 2015] [wsgi:error] [pid 30806:tid > 140269963933440] [remote 95.90.251.8:24357] File > "/home/chris/IT/Portal/veportal/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py" > , line 195, in __call__ > [Thu Dec 17 21:08:23.317982 2015] [wsgi:error] [pid 30806:tid > 140269963933440] [remote 95.90.251.8:24357] response_headers.append(( > str('Set-Cookie'), str(c.output(header='')))) > [Thu Dec 17 21:08:23.317993 2015] [wsgi:error] [pid 30806:tid > 140269963933440] [remote 95.90.251.8:24357] File > "/usr/lib/python2.7/Cookie.py", line 466, in output > [Thu Dec 17 21:08:23.318106 2015] [wsgi:error] [pid 30806:tid > 140269963933440] [remote 95.90.251.8:24357] return "%s %s" % ( header, > self.OutputString(attrs) ) > [Thu Dec 17 21:08:23.318116 2015] [wsgi:error] [pid 30806:tid > 140269963933440] [remote 95.90.251.8:24357] File > "/usr/lib/python2.7/Cookie.py", line 514, in OutputString > [Thu Dec 17 21:08:23.318128 2015] [wsgi:error] [pid 30806:tid > 140269963933440] [remote 95.90.251.8:24357] return _semispacejoin( > result) > [Thu Dec 17 21:08:23.318143 2015] [wsgi:error] [pid 30806:tid > 140269963933440] [remote 95.90.251.8:24357] UnicodeDecodeError: 'ascii' > codec can't decode byte 0xc3 in position 16: ordinal not in range(128) > > After some digging I found that this error was caused by the "set_cookie" > method in mezzanine.utils.views. When creating the "expires" date the > locale de_DE, utf-8 is used by strftime and the month of March in German > contains a non ASCII character (i.e. "Umlaut"). Therefore the error only > pops up if a cookie with expiry "March" is set. > > For testing purposes I tried running my project using the Django > development server in the production environment - strangely enough I did > NOT get the error there. > > As a quick fix I temporarily set the locale back to en_US, utf-8 before > setting the cookie using this > <http://stackoverflow.com/questions/18593661/how-do-i-strftime-a-date-object-in-a-different-locale> > approach; i.e. mezzanine.utils.views like so: > > # This is a hack to avoid unicode decode errors caused on the production > server > # by a german expiry date > > import locale > import threading > > from contextlib import contextmanager > > > LOCALE_LOCK = threading.Lock() > > @contextmanager > def setlocale(name): > with LOCALE_LOCK: > saved = locale.setlocale(locale.LC_ALL) > try: > yield locale.setlocale(locale.LC_ALL, name) > finally: > locale.setlocale(locale.LC_ALL, saved) > > > # End of hack > > > def set_cookie(response, name, value, expiry_seconds=None, secure=False): > """ > Set cookie wrapper that allows number of seconds to be given as the > expiry time, and ensures values are correctly encoded. > """ > if expiry_seconds is None: > expiry_seconds = 90 * 24 * 60 * 60 # Default to 90 days. > # Set back locale to avoid UnicodeDecodeError > with setlocale(('en', 'utf-8')): > expires = datetime.strftime(datetime.utcnow() + > timedelta(seconds=expiry_seconds), > "%a, %d-%b-%Y %H:%M:%S GMT") > # Django doesn't seem to support unicode cookie keys correctly on > # Python 2. Work around by encoding it. See > # https://code.djangoproject.com/ticket/19802 > try: > response.set_cookie(name, value, expires=expires, secure=secure) > except (KeyError, TypeError): > response.set_cookie(name.encode('utf-8'), value, expires=expires, > secure=secure) > > Although things seem to be working now I do not think fiddling with core > code is a good idea. I am not even sure whether this is really a Mezzanine > issue or whether it has something todo with Apache, mod_wsgi or an issue > with the setup of the production server as such. > > Any thoughts welcome. > > Regards > > Chris > > > > > -- > You received this message because you are subscribed to the Google Groups > "Mezzanine Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- Stephen McDonald http://jupo.org -- You received this message because you are subscribed to the Google Groups "Mezzanine Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
