On-Line Библиотека www.XServer.ru - учебники, книги, статьи, документация, нормативная литература.
       Главная         В избранное         Контакты        Карта сайта   
    Навигация XServer.ru






 

Загрузка файлов на сервер и посылка e-mail с вложениями

Одним из популярнейших вопросов во всевозможных форумах является вопрос 'Как загрузить файл на сервер?'. А ведь на самом деле это не так сложно, как кажется на первый взгляд. И чтобы не было совсем легко - пусть скрипт, который приведен ниже еще и посылает этот файл по почте, в виде вложения.

Для использования скрипта нужно установить 2 модуля: MIME::Lite и CGI

Второй скорее всего у вас есть, а первый необходимо скачать.

Приступим к разбору листинга:

Строчки с первой по третью не делают ничего очень важного. Первая - стандартное начало любого скрипта, вторая и третья - по вкусу.

5-12 строки - конфигурация скрипта:

Cтроки 7,8,9 - параметры письма (соответственно от кого, к кому и тема)

Cтрока 10 - значение INCLUDE_META, которое если равно 1, то в письмо включается еще одно вложение с различной служебной информацией: о загруженном файле, переменных окружения и т.д.

Строка 14 - подключение модуля CGI.pm. Здесь не используется объектно-ориентированный интерфейс, а просто импортируются все функции.

16 строка - получение переданных браузером параметров, если они есть. Если в процессе закачки файла возникнет ошибка, то скрипт сразу прервет свою работу и сообщит об ошибке (cgi_error()). При проверке в Perl 5.0 под Windows я столкнулся с ошибкой - обругали меня за то, что функции cgi_error() нет. Пришлось сходить на CPAN.org и взять новую версию CGI.pm (в моем случае это была версия 2.74)

Строки с 22 по 37 выводят форму для загрузки файла. Форма объявляется как multipart, в HTML-виде это выглядит так: enctype="multipart/form-data". Строка 29 - специальное поле для загрузки файла, в браузере оно отображается с кнопочкой 'Обзор' (или 'Browse') справа.

Строки 30 и 31 предлагают пользователю определить, как будет передаваться файл - как текст (mime-тип: quoted-printable) или как бинарник (тип: base64)

Форма закончилась - начался разбор параметров. Если скрипт вызывается первый раз - то здесь его работа закончится, а если пользователь нажимает кнопку Upload - то далее идет обработка:

Строка 40 - подключение модуля MIME::Lite

Строка 41 и 42 - получение файла, который пользователь загрузил и информации о нем в переменные $file и $info. $file в зависимости от контекста - и файл, и строка.

Строки 43-45 создают объект-письмо $msg. Ему присваиваются поля 'от кого', 'кому' и 'тема' - ведь письмо должно куда-то придти.

Если включен конфигурационный параметр INCLUDE_META - строки с 46 по 56 создают первое вложение в письмо, содержащее служебную информацию. Если вдруг в этой служебной информации будут русские буквы - то лучше Encoding поменять на 8bit.

Строки 57-65 выполняют основную работу - создают вложение-файл, закачанный пользователем. 58-60 строки - выбор типа вложения, в зависимости от того, который был указан в форме.

Ну и последние строчки скрипта - с 66 по 74 - отправляют сообщение по почте. Здесь используется метод send_by_smtp(), он более универсален, однако использует модуль Net::SMTP. Можно также использовать send_by_sendmail() (тогда sendmail будет искаться в /usr/lib/, что можно поменять, передав параметр Sendmail=>:, подробнее смотрите в модуле MIME::Lite)

А если при передаче произошла ошибка при отправке письма - то скрипт просто выдаст пользователю на страницу все что должен был отправить по почте.

Вот такой хороший скриптик. Может быть он и не будет работать на вашем сервере сам по себе, но зато его части очень даже можно использовать в любом проекте.

Листинг:

        =1=     #!/usr/bin/perl -w
        =2=     use strict;
        =3=     $|++;
        =4=     
        =5=     ## configuration
        =6=     
        =7=     my $FROM = 'webmaster@your.site';
        =8=     my $TO = 'upload@your.site';
        =9=     my $SUBJECT = 'File upload';
        =10=    my $INCLUDE_META = 1;
        =11=    
        =12=    ## end configuration
        =13=    
        =14=    use CGI qw(:all);
        =15=    
        =16=    my @params = param();
        =17=    if (my $error = cgi_error()) {
        =18=      print header(-status => $error);
        =19=      exit 0;
        =20=    }
        =21=    
        =22=    print
        =23=      header,
        =24=      start_html("Upload"),
        =25=      h1("Upload"),
        =26=      hr,
        =27=      start_multipart_form,
        =28=      table(Tr(td(p('upload:')),
        =29=               td(filefield('uploaded_file'))),
        =30=            Tr(td(p('email as type:')),
        =31=               td(radio_group('type', [qw(binary text)]))),

        =35=            Tr(td({ -colspan => 2 }, submit))),
        =36=      end_multipart_form,
        =37=      hr;
        =38=    
        =39=    if (@params) {
        =40=      require MIME::Lite;
        =41=      if (my $file = upload('uploaded_file')) {
        =42=        my $info = uploadInfo($file) or die "info?";
        =43=        my $msg = MIME::Lite->new
        =44=          (Type => 'multipart/mixed',
        =45=           From => $FROM, To => $TO, Subject => $SUBJECT);
        =46=        if ($INCLUDE_META) {
        =47=          $msg->attach
        =48=            (Type => 'TEXT', Encoding => '7bit',
        =49=             Data => [
        =50=                      "Upload info:\n",
        =51=                      (map { "$_ => $info->{$_}\n" } sort keys %$info),
        =52=                      "ENV:\n",
        =53=                      (map { "$_ => $ENV{$_}\n" } sort keys %ENV),
        =54=                     ],
        =55=            );
        =56=        }
        =57=        $msg->attach
        =58=          ((param('type') eq 'text' ?
        =59=            (Type => 'TEXT', Encoding => 'quoted-printable') :
        =60=            (Type => 'BINARY', Encoding => 'base64')),
        =64=            (FH => $file)),
        =65=          );
        =66=        if ($msg->send_by_smtp('localhost')) {
        =67=          print p("Upload sent by email.");
        =68=        } else {
        =69=          print
        =70=            p("An error occurred... here's what would have been sent:"),
        =71=            pre($msg->as_string);
        =72=        }
        =73=      }
        =74=    }
        =75=    print end_html;


Литература по Perl