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 mezzanine-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.