Seite 1 von 1

LC_ALL für MOD_WSGI Applikation definieren

Verfasst: Montag 29. Dezember 2008, 01:07
von DatenMetzgerX
Hallo Zusammen

Ich habe folgendes Problem, meine Anwendung liest die Ordnerstruktur vom Filesystem aus und zeigt diese schlussendlich als Seite an (ähnlich wie ListDirectory von Apache).
Der apache User hat das normale ANSI_X3.4-1968 encoding, die meisten Dateien auf der Harddisk sind jedoch im UTF-8 Format gespeichert. Wenn ich nun os.listdir() mit einem unicode-String aufrufe, versucht die Methode die Dateinamen in Unicode umzuwandeln und verwendet hierfür das Encoding das sys.getfilesystemencoding() liefert. Dies ist natürlich ANSI_X3.4-1968 und kann nicht alle UTF-8 Zeichen repräsentieren. Dies führt dann unweigerlich zu einem UnicodeDecodeError.

Gibt es eine Möglichkeit mod_wsgi beizubringen welches Encoding die Applikation nutzen soll? Oder gehe ich das Problem falsch an?

Gruess + Dank
Dm

Verfasst: Montag 29. Dezember 2008, 01:12
von veers
Setzt doch einfach die LANG Umgebungsvariable entsprechend.

Verfasst: Montag 29. Dezember 2008, 01:20
von DatenMetzgerX
Das war auch mein erster Gedanken, okey evtl. tue ich es am falschen Ort.

In meinem WSGI Script habe ich folgendes hinzugefügt, leider ohne Wirkung.

Code: Alles auswählen

process = subprocess.Popen("export LC_ALL=de_DE@UTF-8", shell=True, stdout=out)

Verfasst: Montag 29. Dezember 2008, 01:40
von veers

Verfasst: Montag 29. Dezember 2008, 04:08
von Leonidas
DatenMetzgerX hat geschrieben:In meinem WSGI Script habe ich folgendes hinzugefügt, leider ohne Wirkung.

Code: Alles auswählen

process = subprocess.Popen("export LC_ALL=de_DE@UTF-8", shell=True, stdout=out)
Natürlich ist völlig effektfrei, da es eine Shell startet, in dieser ``LC_ALL`` definiert und die Shell wieder beendet, womit auch die Definition von ``LC_ALL`` verschwindet. Übrigens kann man, wenn man ``Popen`` verwendet, Umgebungsvariablen mittels des ``env``-Parameters übergeben; es ist also unnötig ``export`` zu nutzen, das sowieso nur in Unix-Shells funktioniert.

Verfasst: Montag 29. Dezember 2008, 10:42
von DatenMetzgerX
Das Ausführen von subprocess.Popen ohne shell ergibt bei mir einen

Code: Alles auswählen

 OSError: [Errno 13] Permission denied
Fehler?

Die Variante mit SetEnv würde mir persönlich ja gefallen, jedoch scheint sie keinen Einfluss auf die Anwendung zu haben, oder jedenfalls nicht was LC_ALL betrifft.

Code: Alles auswählen

<VirtualHost *:80>
        ServerName server.ch
        ServerAlias server.ch
        SetEnv  LC_ALL  de_DE@UTF-8

        ErrorLog        /var/log/httpd/error_fileshare.log
        CustomLog	/var/log/httpd/access_fileshare.log common

        DocumentRoot /usr/local/www/documents

        <Directory /usr/local/www/documents>
                Order allow,deny
                Allow from all
        </Directory>

        WSGIScriptAlias /	/usr/local/www/wsgi/server.wsgi

        <Directory /usr/local/www/wsgi>
                Order allow,deny
                Allow from all
        </Directory>
</VirtualHost>

Verfasst: Montag 29. Dezember 2008, 13:08
von Leonidas
DatenMetzgerX hat geschrieben:Das Ausführen von subprocess.Popen ohne shell ergibt bei mir einen

Code: Alles auswählen

 OSError: [Errno 13] Permission denied
Fehler?
``subprocess.Popen`` macht ja generell keinen Sinn, da Umgebungsvariablen der Elternprozesse an Kindprozesse weitergegeben werden, nicht andersrum. Wenn du eine Umgebungsvariable in einem Kindprozesse (der Shell) änderst, dann ist diese nur in der Shell gesetzt. Da die Shell danach sich sofort beendet, verschwindet auch die Variable.

Hast du nachgeschaut, was für Umgebungsvariablen in deiner WSGI-Applikation gesetzt sind?

Verfasst: Montag 29. Dezember 2008, 16:09
von DatenMetzgerX
Die $LANG Variabel hat den wert 'C'?! Wenn ich die Werte mit os.environ["LANG"] = 'de_CH.UTF-8' überschreibe steht dann zwar das richtige drin, hat jedoch keinen Einfluss auf sys.getfilesystemencoding().

Mein nächster Versuch war die locale des Systems in /etc/environment einzutragen. Diese greifen für das ganze System, nur nicht für meinen WSGI Prozess.

Daraufhin habe ich noch die Variabeln LC_ALL, LANG, LANGUAGE zu PassEnv hinzugefügt in der Apache konfiguraiton. LC_ALL & LANGUAGE scheinen zu greifen, LANG behält jedoch den Wert 'C'.

Langsam sehe ich echt nicht mehr durch...
Das mit dem Encoding des Filesystems und Python habe ich übrigens von hier

Dankschön DM