IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Web Perl Discussion :

Authentification et accès à des fichiers


Sujet :

Web Perl

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 161
    Points : 116
    Points
    116
    Par défaut Authentification et accès à des fichiers
    Bonjour,

    Je suis actuellement bloqué par un problème.
    Pour vérifier si une personne à le droit d'accéder à un fichier je passe par un script perl auquel j'envoie une session et l'identifiant d'un fichier.
    Si la personne est autorisée j'envoie le fichier via le script perl. Le seul problème c'est que ça prend énormément de ressources.

    N'y a t-il pas un moyen de dire à apache d'envoyer une session et un idfichier à un script perl. Puis le script perl dirait à Apache ou aller chercher le fichier si la session est bonne ?

    Merci d'avance pour votre aide.

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par YanK
    Bonjour,

    Je suis actuellement bloqué par un problème.
    Pour vérifier si une personne à le droit d'accéder à un fichier je passe par un script perl auquel j'envoie une session et l'identifiant d'un fichier.
    Si la personne est autorisée j'envoie le fichier via le script perl. Le seul problème c'est que ça prend énormément de ressources.

    N'y a t-il pas un moyen de dire à apache d'envoyer une session et un idfichier à un script perl. Puis le script perl dirait à Apache ou aller chercher le fichier si la session est bonne ?

    Merci d'avance pour votre aide.
    Une redirection ? Néanmoins cela pose un problème de sécurité... Que fais-tu pour faire transiter le fichier par ton script ? Ca ne devrait pas prendre tant de ressources, sauf si tu le fais ligne à ligne pour un gros fichier.

    --
    Jedaï

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 161
    Points : 116
    Points
    116
    Par défaut
    Oui c'est exactement ça je lis ligne par ligne le fichier. J'ai pas trouvé comment l'envoyer autrement.
    Du coup ça montre en mémoire le fichier, ça met du temps et ça prend pas mal de ressource.

  4. #4
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par YanK
    Oui c'est exactement ça je lis ligne par ligne le fichier. J'ai pas trouvé comment l'envoyer autrement.
    Du coup ça montre en mémoire le fichier, ça met du temps et ça prend pas mal de ressource.
    Lorsque tu n'as pas besoin d'examiner le fichier, il est largement préférable de le lire par bloc avec la fonction read() (si ce n'est sysread(), encore plus rapide, mais plus délicat, après tout on n'utilise pas Perl pour écrire du C ) et de l'écrire par bloc en sortie (print convient parfaitement pour ça), ne me dis pas que tu le lisais ligne par ligne et que tu le stockais entièrement en mémoire avant de l'envoyer ?

    --
    Jedaï

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 161
    Points : 116
    Points
    116
    Par défaut
    Je sais pas si je dois répondre a cette question.
    Je vais essayer "read()" et "sysread()" pour voir.
    Merci beaucoup.

    Je mettrais les résultats et les différences.
    Je me disais aussi que c'était pas possible de rien trouver de mieux pour passer un fichier. J'adore perl on fait des trucs de fou, c'etait le seul truc puissant que j'arrivais pas à faire avec.

  6. #6
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Après un petit benchmark, il apparaît que sur mon système au moins, sysread() est légèrement plus performant que read(), mais c'est trop léger pour être notable. Par contre ce qui est tout sauf léger, c'est la différence entre n'importe laquelle de ces solutions et la lecture ligne par ligne... J'ai quelque chose comme un facteur 500 de différence sur mon ordinateur !!

    Une alternative pratique est d'utiliser File::Copy (dans le CORE depuis l'origine des temps (Perl 5.2), donc on s'assure une excellente portabilité), et sa fonction copy(), ce qui permet de résoudre le problème en deux lignes avec des performances parfaitement honorable (peut-être 1/4 plus lent que la solution à la main sur mon ordinateur) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    use File::Copy;
    my $filepath = 'your_file';
    copy $filepath, \*STDOUT
      or die "Coudn't copy $filepath : $!\n";
    --
    Jedaï

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 161
    Points : 116
    Points
    116
    Par défaut
    Je crois que je vais poser encore une question bête.
    J'ai essayé le code que tu m'as envoyé dans ton dernier message, il renvoie bien le fichier demandé seulement mes entêtes http se retrouve après le fichier.

    Je m'explique, je fais ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print "Content-type:image/jpg\n\n";
    copy ($IdFichier, \*STDOUT);
    J'ai essayé "print STDOUT" mais ça marche pas non plus.
    Le script envoie le fichier puis les entêtes.

  8. #8
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Intéressant ! C'est à cause de l'emploi de syswrite() dans File::Copy, qui fait une écriture non-bufferisée au contraire de print(). Comme syswrite() ne tient même pas compte du tout du buffer (il n'essaie pas de le flush()er), il écrit avant que le buffer rempli par les print() soit vidé, d'où la perturbation constaté du flux de sortie.
    Rajoute :
    Au début de ton script pour activer l'autoflush sur STDOUT et tout devrait marcher comme prévu.

    --
    Jedaï

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 161
    Points : 116
    Points
    116
    Par défaut
    Ca marche merci, mais du coup de passer par un buffer est ce que je ne ralenti pas le processus comme avant ?

    Ne serait t-il pas mieux d'envoyer les entêtes sans bufferisation. Bon dit comme ça, ça parrait simple, mais je sais même pas si c'est possible.

  10. #10
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par YanK
    Ca marche merci, mais du coup de passer par un buffer est ce que je ne ralenti pas le processus comme avant ?

    Ne serait t-il pas mieux d'envoyer les entêtes sans bufferisation. Bon dit comme ça, ça parrait simple, mais je sais même pas si c'est possible.
    Non, tu n'as pas bien compris : print() utilise toujours un buffer, ceci afin d'accélérer les entrées-sorties en évitant de faire un appel système pour chaque octet (les appels systèmes sont LENT, quel que soit l'OS, par rapport à du code s'exécutant exclusivement en Userland. Si tu ne comprends rien à ce que je dis, ne t'inquiète pas, tout ce que tu as besoin de savoir, c'est que Perl fait "Ce qu'il Faut" pour que ça marche et que ce soit le plus rapide possible). Ce que $| commande c'est ce qu'on appelle l'autoflush, c'est-à-dire que si $| a une valeur vraie, un flush() (un vidage du buffer) est exécuté après chaque commande print(), au final on obtient un effet équivalent à si print() n'utilisait plus de buffer (bien que ce ne soit pas réellement ce qui se passe).
    syswrite() qui est utilisé dans File::Copy est une fonction de bien plus bas niveau, qui n'utilise jamais de buffer mais fait directement appel à write(), l'appel système (à ne pas confondre avec la fonction write() de Perl qui fait entièrement autre chose, normalement tu ne devrais jamais l'utiliser, pas plus que syswrite() d'ailleurs).

    Passer par un buffer est le comportement normal de Perl, et c'est le comportement le plus rapide, en général, en terme de débit (bien qu'il puisse poser des problèmes de responsivité en contrepartie, mais ceci est une autre histoire). $|=1 désactive ce buffer (ou plutôt fait en sorte qu'on ne le remarque pas)

    En conclusion : Si tu mets $|=1 et utilise File::Copy, il n'y aura aucune bufferisation dans ton programme, mais ceci ne le ralentira pas car de toute façon, tu n'as qu'un seul print() et File::Copy utilise syswrite() sur des blocs d'une taille telle qu'un buffer serait plutôt une gêne, même s'il était possible d'en utiliser un.

    --
    Jedaï

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 161
    Points : 116
    Points
    116
    Par défaut
    Merci beaucoup pour toutes ces réponses. Ca m'a éclairci pas mal de choses.
    Je fais plusieurs print en fait j'avais simplifié mon code pour éviter de faire un truc trop compliqué. Je vais essayer de faire en sorte de les rassembler en un seul au lieu de 3 ou 4.

    Encore merci pour ton aide.

  12. #12
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par YanK
    Je fais plusieurs print en fait j'avais simplifié mon code pour éviter de faire un truc trop compliqué. Je vais essayer de faire en sorte de les rassembler en un seul au lieu de 3 ou 4.
    Ne t'inquiète pas de ce genre de détails... Si tu en faisais 1000 peut-être... Mais suroptimiser rend le code illisible et consomme un temps précieux. Tu gagneras peut-être un millième de seconde sur une telle optimisation, et encore !!

    --
    Jedaï

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    161
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 161
    Points : 116
    Points
    116
    Par défaut
    Ok merci beaucoup.
    J'essayerais de voir si je peux pas accélérer encore tout ça avec un système de cache.
    J'éviterais des requêtes mysql qui ajoutent du temps à la réponse.

    En tout cas merci pour ton aide.

  14. #14
    Membre à l'essai
    Inscrit en
    Février 2004
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 14
    Points : 11
    Points
    11
    Par défaut une pincée de mod_perl ?
    Salut à tous,
    Je vais sans doute dire une bêtise :
    Je me demande si en couplant les modifications conseillées par Jedai avec mod_perl tu ne gagnerais pas d'une autre manière.

    Quelqu'un a un avis constructif ?

  15. #15
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    mod_perl accélère considérablement l'utilisation de Perl pour du côté serveur (encore que si c'est juste pour l'accélération, FastCGI avec lighttpd puisse être une bonne solution aussi) donc accélèrerait sans doute la vitesse de service de la page. Evidemment, mod_perl ne rend pas le code Perl plus rapide, il se contente d'éviter la phase de création de processus et de chargement et compilation du code, donc si YanK avait conservé son premier code, passer à mod_perl ne l'aurait pas aidé du tout.

    --
    Jedaï

  16. #16
    Membre à l'essai
    Inscrit en
    Février 2004
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 14
    Points : 11
    Points
    11
    Par défaut
    Ok merci Jedai pour cette précision. C'est un peu cette idée que je sous entendais lorsque j'évoquais d'une autre manière.

    Remarque c'est vrai que c'est un peu hors propos et valable pour pas mal de cgi d'après ce qui se dit. Mea culpa

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. accès à des fichiers par une japplet
    Par gabest dans le forum Applets
    Réponses: 4
    Dernier message: 27/05/2006, 17h39
  2. [FPDF] création d'un interface pour accés à des fichiers PDF
    Par StyleXP dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 19/12/2005, 10h18
  3. accés à des fichiers *.db
    Par wincroc dans le forum Bases de données
    Réponses: 4
    Dernier message: 16/08/2005, 14h48
  4. Chemin d'accès des fichiers dans des sous rep
    Par Le Veilleur dans le forum C++Builder
    Réponses: 4
    Dernier message: 17/11/2004, 14h37
  5. Restreindre l'accès des fichiers..
    Par Neilos dans le forum Windows
    Réponses: 6
    Dernier message: 25/08/2004, 00h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo