2009-04-28 5 views
1

Je suis nouveau sur mod_python et Apache, et j'ai du mal à retourner un fichier à un utilisateur après une requête GET. J'ai une configuration très simple en ce moment, et espérais ouvrir simplement le fichier et l'écrire à la réponse:Comment ouvrir et transférer un fichier sur le système de fichiers dans mod_python?

from mod_python import apache 

def handler(req): 
    req.content_type = 'application/octet-stream' 
    fIn = open('response.bin', 'rb') 
    req.write(fIn.read()) 
    fIn.close() 
    return apache.OK 

Cependant, je reçois des erreurs lors de l'utilisation ouverte(), en disant que la le fichier n'existe pas (même si j'ai vérifié une douzaine de fois qu'il le fait). Cela se produit lors de l'utilisation de chemins de fichiers relatifs et absolus.

J'ai deux questions:

  • Pourquoi n'est pas ouvert() trouver le bon fichiers?
  • Quelle est la meilleure façon de retourner un fichier à partir du système de fichiers? (Je demande de faire que je ne manque pas une meilleure façon d'utiliser mod_python pour retourner un fichier.)

Merci

Edit: Après avoir trouvé ce fil: http://www.programmingforums.org/thread12384.html j'ai découvert que open() fonctionne pour moi si je déplace le fichier vers un autre répertoire en dehors de la maison (j'ai été alias hors de/home/myname/httpdocs, mais cela fonctionne si j'utilise/data). Des idées pour lesquelles cela fonctionne?

Edit 2: Une partie de mon erreur de débogage, comme l'a demandé:

MOD_PYTHON ERROR 

ProcessId:  13642 
Interpreter: '127.0.1.1' 

ServerName:  '127.0.1.1' 
DocumentRoot: '/var/www' 

URI:   '/test/mptest.py' 
Location:  None 
Directory:  '/home/myname/httpdocs/' 
Filename:  '/home/myname/httpdocs/mptest.py' 
PathInfo:  '' 

Phase:   'PythonHandler' 
Handler:  'mptest' 

Traceback (most recent call last): 

    File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1537, in HandlerDispatch 
    default=default_handler, arg=req, silent=hlist.silent) 

    File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1229, in _process_target 
    result = _execute_target(config, req, object, arg) 

    File "/usr/lib/python2.5/site-packages/mod_python/importer.py", line 1128, in _execute_target 
    result = object(arg) 

    File "/home/myname/httpdocs/mptest.py", line 13, in handler 
    fIn = open('/home/myname/httpdocs/files/response.bin', 'rb') 

IOError: [Errno 2] No such file or directory: '/home/myname/httpdocs/files/response.bin' 

Répondre

4

Pour déboguer ce genre de chose, vous devez recueillir toutes les informations de l'instance mod_python en cours d'exécution. Arrêtez de jouer avec "vérifier une douzaine de fois qu'il existe [existe]". Certaines hypothèses ne sont pas correctes.

Procédez comme suit pour obtenir des informations de débogage.

def handler(req): 
    req.content_type = 'text/plain' 
    req.write(os.environ) 
    req.write(os.getcwd()) 
    # etc. 
    return apache.OK 

Modifier

Maintenant vous avez un aperçu de la Stuff Important. Dans ce cas, il peut s'agir d'autorisations - vous devez utiliser os.filestat pour être sûr. Apache exécute mod_python en tant qu'utilisateur n'ayant pratiquement aucune autorisation utilisable. Apache n'aime pas non plus les liens, mais cela ne devrait pas affecter mod_python. Si votre fichier n'a pas read-by-tout le monde et n'est pas dans le bon répertoire, vous aurez des problèmes. Vous pouvez passer à mod_wsgi.

+0

J'ai mis à jour ma question après avoir trouvé un indice sur ce qui se passe. J'ai aussi essayé votre conseil et découvert quelques faits intéressants: mod_python s'exécute comme "www-data", et n'a plus de "/". –

0

Pouvez-vous coller l'erreur (s) que vous obtenez?

Il s'agit probablement d'une erreur d'autorisation (si vous avez essayé d'utiliser le chemin d'accès complet au fichier). Souvenez-vous que le script s'exécute en tant qu'utilisateur exécutant le processus du serveur Web. Vous accéderez donc au fichier en tant que "www-data", ou "personne" en général.

Vérifiez également les autorisations du dossier /home/myname/httpdocs/files/.Le dossier doit être +x pour l'utilisateur www-data:

$ mkdir blah 
$ echo works > blah/response.bin 
$ chmod 000 blah/ 
$ cat blah/response.bin 
cat: blah/response.bin: Permission denied 
$ chmod +x blah/ 
$ cat blah/response.bin 
works 

Vous pouvez éliminer Apache/votre script de l'équation en procédant comme suit:

you:~$ sudo su - www-data 
www-data:~$ file /home/myname/httpdocs/files/response.bin 

(le su peut ne pas fonctionner, selon le OS/distribution que vous utilisez, par exemple OS X vous empêche de vous connecter comme www utilisateur)

Autorisations de fichiers mises à part, pourquoi le script est-il dépendant d'un fichier dans votre dossier de départ? Est-ce que response.bin peut être déplacé dans le même dossier que votre script Python? Ou peut-être même déplacé dans une base de données? (Peut-être SQLite? Peut-être inutile/excessif, selon ce qui est response.bin et combien il change)

+1

J'ai collé la plupart des erreurs à ma question. Cependant, j'ai essayé de chowner les fichiers sur www-data sans succès. (Peut-être que je me méprends sur les permissions du système d'exploitation Unix, cependant) –

Questions connexes