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.

Reply via email to