Perl没有写入缓冲区

时间:2016-05-09 18:18:15

标签: perl upload

多年来,我使用以下从站点下载的perl代码将文件上传到我们的linux服务器。基本上,用户在html表单中键入用户名和密码,选择要上载的文件,然后单击“提交”。该脚本完成剩下的工作。由于某种原因上周,脚本停止工作。我知道它正在打开要写入的文件,因为我试图注释掉'unlink'行,如果没有写入文件就会删除该文件。它确实打开文件在服务器上写入,但是当我打开文件时,那里什么都没有。我已经尝试更改存储上载文件的目录上的文件权限和所有权,但没有任何结果。任何想法或建议?谢谢!

limit nofile 65535 65535

}

 my $DATA_DIR = '/Absolute/path/to/datadir/';   # Path of data directory
 my $DEFAULT_UPLOAD_DIR = '/tmp/'; #used only if you don't use password.

 my $MAX_SIZE_UPLOAD = 25; # Ko
 # File sizes are limited to $MAX_SIZE_UPLOAD (0 No limit), larger files will
 # return an 'Internal Server Error'.

 my $FORM_URL = 'http://www.yourdomain.com/upload.html';

 my $WEBMASTER_EMAIL = 'you@yourdomain.com';

 my $DISPLAY_LANG = 'En'; # Fr -> french

 my $USE_PASSWORD_PROTECT = 1; # 1 to use password protect 0 else.
 my $PASSWORD_FILE = $DATA_DIR.'password.txt'; # Name of Password file

 # En: Define all messages and buttons text.
 # Fr: Definition des messages et des boutons
 my(%NAME_BUTTON, %NAME_HEADTAB, %NAME_TITLE);

 if ($DISPLAY_LANG eq 'Fr') {
%NAME_BUTTON = ('exit' => 'Sortir', 'back' => 'Retour', 'add' => 'Ok', 
    'add_user' => 'Ajouter', 'edit_user' => 'Edit', 'del_user' => 'Supprimer',  'log' => 'Entrer');
 %NAME_HEADTAB = ('name' => 'Nom', 'level' => 'Droits', 'user_path' => 'Répertoire utilisateur',
    'login' => 'Identifiant', 'password' => 'Mot de passe', 'new_login' => 'Nouvel identifiant',
    'new_pass' => 'Nouveau mot de passe', 'conf_pass' => 'Confimer mot de passe',
    'admin' => 'Administrateur', 'member' => 'Membre', 'w_path' => "(Chemin inexistant !)");
%NAME_TITLE   = ('common_admin' => "eUpload, écran d'administration", 'common_member' => 'eUpload, écran de chargement',
    'error_form' => 'Erreur : Formulaire incomplet', 'manage_users' => 'Management des utilisateurs', 'edit_user' => "Editer 'Value_login' utilisateur", 'add_user' => 'Ajout d\'un utilisateur',
    'user_saved' => "Utilisateur 'Value_login' savé", 'user_added' => "Nouvel utilisateur 'Value_login' ajouté", 'user_deleted' => "Utilisateur 'Value_new_login' supprimé",
    'change_pass' => 'Changer votre mot de passe', 'chpass_invalid' => 'Nouveau mot de passe invalide', 'chpass_updated' => 'Mot de passe de Value_login mis à jour',
    'enter_pass' => 'Entrer votre mot de passe', 'invalid_pass' => 'MOT de PASSE INCORECT',
    'EU_BadFN' => "Error: Nom de fichier 'Value_FileName' incorrect", 'EU_FExist' => "Error: Fichier 'Value_FileName' existant, impossible de le modifier!",
    'EU_Size' => "Error: Erreur de chargement de 'Value_FileName'", 'Upload_Succes' => 'Chargement réussi !',
    'Upload_Succes_txt' => "'Value_FileName' (Value_Size bytes, Value_Time s) est sauvé");
 } else {
%NAME_BUTTON = ('exit' => 'Exit', 'back' => 'Back', 'add' => 'Ok', 
    'add_user' => 'Add', 'edit_user' => 'Edit', 'del_user' => 'Remove', 'log' => 'Log in');
%NAME_HEADTAB = ('name' => 'Name', 'level' => 'Level', 'user_path' => "User path",
    'login' => 'Login', 'password' => 'Password', 'new_login' => 'New Login',
    'new_pass' => 'New password', 'conf_pass' => 'Confim password',
    'admin' => 'Administrator', 'member' => 'Member', 'w_path' => "(Path don't exist !)");
%NAME_TITLE  = ('common_admin' => "eUpload, administrative display", 'common_member' => "eUpload, upload display",
    'error_form' => 'Error : Incomplet form', 'manage_users' => 'Manage Users', 'edit_user' => "Edit 'Value_login' user", 'add_user' => 'Add a user',
    'user_saved' => "User 'Value_login' saved", 'user_added' => "New user 'Value_login' added", 'user_deleted' => "User 'Value_new_login' deleted",
    'enter_pass' => 'Enter your password', 'invalid_pass' => 'INVALID PASSWORD',
    'EU_BadFN' => "Error: Bad Name 'Value_FileName'", 'EU_FExist' => "Error: File 'Value_FileName' exists, can not overwrite !",
    'EU_Size' => "Error: Could not upload file: 'Value_FileName'", 'Upload_Succes' => 'Upload uploaded successfully!',
    'Upload_Succes_txt' => "'Value_FileName' (Value_Size bytes, Value_Time s) was saved");

1 个答案:

答案 0 :(得分:1)

很明显,问题在于在显示的代码之外(之前)上传文件。代码打印到$file_name,通过清理$file_query来获取$query。这是传递给sub的CGI对象本身。我在代码中看不到任何会混淆用于编写$file_name的数据的内容。

这意味着$file_query文件句柄的数据(有时)会丢失,因此当您通过read()循环将其复制到$file_name时,您什么也得不到。

我可以推荐的一件事是测试被复制到$file_name的(temp)文件的大小。 请参阅下面的更新,了解如何执行此操作。任何其他诊断都必须在其他地方进行,所以看起来似乎。

另一种(遥远的?)可能性是从$query拉出的文件句柄已被用于读取(或写入)并且不再指向文件的开头 - 而是指向结尾。这也不在显示的代码中。 更新:可能值得在seek $query_file, 0, 0循环之前尝试read,以'回放'到文件的开头。

代码可以改进但我不知道它是如何导致这个问题的。

<强>更新

脚本通过read($file_query, ...)读取,其中$file_query先前由

设置
$_ = $file_query = $query->param('file')

query->param返回事物的名称,而read需要文件句柄。通过CGI的方便,param 返回的内容也可以用作文件句柄。但是,通过方法$query->upload('file')从CGI对象中正确获取文件句柄。

然后值得尝试通过upload方法获取文件句柄,并在read循环中使用它,而不是$file_query。请参阅File upload文档中的CGI部分。

更新

来自CGI.pm docs中的File upload

  

处理上传的文件时,CGI.pm会在硬盘上创建一个临时文件,并将文件句柄传递给该文件。

检查文件以查看该文件是否完全进入服务器。在upload() sub之前执行此操作。链接的文档给我们

my $fh_tmp  = $query->upload( 'file' );
my $tmpfilename = $query->tmpFileName( $fh_tmp );

现在可以查询$tmpfilename的大小,例如,您的代码使用相同的stat来检查$file_name大小,或者只使用Perl的file-test operators

(if -z $tmpfilename)  { print "Empty file (exists but zero size)!\n" }

如果 文件为零大小,则表示问题较早。