1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.

Perl - загрузка файлов через HTTP (web форма)

Тема в разделе "Программирование", создана пользователем ViT, 29.06.05.

  1. ViT

    ViT Активный участник

    998
    0
    Нужна загрузка файлов с web-формы (HTTP) - фото, картинки, файлы.
    Это вроде делается с помощью cgi-lib.pl и как-то без него.
    Cgi-lib.pl у меня имеется версии 2.8
    Пробовал сделать по этому образцу:
    http://cgi-lib.berkeley.edu/ex/perl5/fup.cgi.txt

    Выдает:
    Error: Unable to open file :
    Error: Unable to delete file
    Error: Unable to delete file : No such file or directory

    В скрипте поменял: $cgi_lib::writefiles = "./foto";
    это, как написано в описании, папка куда будет сохранен файл.
    И папка такая есть и все есть, но не работает.
     
  2. Slv

    Slv Активный участник

    1.202
    49
    ПРАВА НА ПАПКУ ПРОВЕРЬ!!
     
  3. ViT

    ViT Активный участник

    998
    0
    Да я пока у себя в винде тестю (Apache, WIN2k).
     
  4. perldev

    perldev Гость

    2 ViT

    Я могу порекомендовать Вам использовать стандартный модуль CGI.pm
    Отличный и весьма простой в использовании.
    На мой взгляд, использование иных библиотек оправданно лишь в том случае, если критичен размер памяти, занимаемой программой, ибо CGI.pm требует около 1.5 Мб во время компиляции и выполнения.

    вот пример кода с использованием CGI.pm
    use CGI;
    my $CGI = new CGI;
    my $param = $CGI->param('name');
    $buffersize = 16384;
    open (OUTFILE,">$filename");
    while (my $bytesread = read($param, my $buffer, $buffersize))
    {
    print OUTFILE $buffer;
    }
    close (OUTFILE);


    В итоге в файле filename содержится файл, переданный через СGI в параметре запроса 'name'.
    Ну и естественно, не забывайте использовать в форме enctype="multipart/formdata"
     
  5. ViT

    ViT Активный участник

    998
    0
    perldev
    большое спасибо!
    утром опробую!
     
  6. ViT

    ViT Активный участник

    998
    0
    perldev
    Не идет

    #!c:\perl\bin\perl
    use CGI;
    use CGI::Carp qw(fatalsToBrowser);
    print "Content-type: text/html\r\n\r\n";

    my $CGI = new CGI;
    my $param = $CGI->param('name');
    $buffersize = 17555;
    open (OUTFILE,">$filename");
    while (my $bytesread = read($param, my $buffer, $buffersize))
    {
    print OUTFILE $buffer;
    }
    close (OUTFILE);

    Все переменные кроме $param и $beffersize нулевой длины - они пустые!
    В $param хранится полный путь до файла на машине юзера, который делает аплоад.
    Все верно? Может чего я пропустил?

    Имя поля в форме - "name", оттуда param'ом и должен вроде как брать файл, но что-то нету :(
     
  7. RubiN

    RubiN Активный участник

    6.629
    425
    тебе перл че-то пишет? в студию..
     
  8. ViT

    ViT Активный участник

    998
    0
    Все, проблема решена.
    Все ок работает!

    Спасибо всем!
     
  9. ViT

    ViT Активный участник

    998
    0
    Ай! Не пойму в чем дело - только сейчас заметил. Все файлы, в которых нет русских букв, загружаются, а те, в названии которых есть русские буквы - нет.

    Почему???
     
  10. Nekto

    Nekto Почётный

    5.710
    0
    ViT
    Дай код срипта загрузки.

    Мы не телепаты
     
  11. ViT

    ViT Активный участник

    998
    0
    Nekto

    my %mtypes = (gif => '', jpg => '', png => '', bmp => '');
    my $fname = param('fname') || '';
    if ($fname ne ''){
    my $fname1 = upload('fname'); # загрузка архива
    $fname =~ s!^.*(\\|\/)!!; # выделяем только имя файла
    $fname =~ s!\"$!!; # " для opera вырезаем кавычку в конце
    $fname =~ /\.(\w+)$/;
    my $ext = $mtypes{$1};
    $type = $1;
    if (exists $mtypes{$1}){
    my $path = "../foto/$fname";
    open FH, ">$path";
    binmode FH;
    my $buffer;
    while (read($fname1, $buffer, 1024)) {
    print FH $buffer;
    }
    close FH;
    # chmod 0644, $path; # -rw-r--r--
    undef $buffer;

    }
    }
     
  12. ViT

    ViT Активный участник

    998
    0
    Nekto
    Отбой! Все решено! - Как полезно ведь бывает попросить у кого-либо совета, и в ожидании ответа самому все решить :))

    Я забыл в хеш %mtypes поместить jpeg, а когда тестил - пробовал в основном на этом формате, причем файлы были то с русскими именами, то в полном пути до файла были рус.буквы, что и привело меня в замешательство :)
     
  13. perldev

    perldev Гость

    2ViT
    Не совсем в тему загрузки файлов, но имхо, определение типа файла по расширению не изящно, ибо юзверь может попытаться обмануть систему. Самый лучший способ - проверить сигнатуру файла. Если с этим неохота заморачиваться - проверьте первые несколько символов файла. Например, в jpeg первое слово всегда 0xffd8, bmp начинается со строки BM, a gif - со строки GIF.
    Также есть хорошие пакеты ImageMagic и GD (правда, самые последние GD для perl перестали поддерживать gif)
     
  14. ViT

    ViT Активный участник

    998
    0
    perldev
    Большое спасибо за совет!
    Я думал про сигнатуру, проверять заголовок файла, но счел это лишним, по крайней мере по началу, а теперь вот думаю что зря. Вы мне лишний раз напомнили про эту идею! Наверное так и сделаю - делов там не много, зато безопаснее.

    С ImageMagic не работал, но читал про этот perl'овый Photoshop :))
    Вы советовали этот пакет для проверки типа файла? Потому как если в этом пакете уже есть такая стандартная функция, так вообще ничего писать не нужно.

    Кстати, perldev , у меня такой вопрос, может Вы в курсе - можно ли без аплоада файла юзером на сервер, предварительно узнать размер этого файла. Ну т.е. это для того, чтобы если вдруг юзер по немнимательности на предупреждение "загружать файлы размером до ХХХ" захочет сделать аплоад файла размером более чем ХХХ, то чтобы система его предупредила заранее, без аплоада, чтобы он и время и трафик не тратил (траф особенно ценен при жпрс-connect'е :))) ... невнимателность - со всяким бывает, а юзеру приятно!

    Что скажете?