Эта тема на forum.dklab.ru


Ant: UPLOAD без использования CGI.PM!
Помогите, может кто знает как это заделать. Есть код, только нерабочий (достал с сайта Xpoint):

Дмитрий Казновский 2001-04-08 14:34:27


Не могу загрузить файлы больше 4 kb. Не могу понять в чем дело. Буду признателен если кто-нибудь подскажет.

#!/usr/bin/perl
#upload.cgi
####################
$userdir=".";

print "Content-type: text/html;\n\n";

if($ENV{'REQUEST_METHOD'} eq 'GET') {$query=$ENV{'QUERY_STRING'};}
elsif($ENV{'REQUEST_METHOD'} eq 'POST') {sysread(STDIN,$query,$ENV{'CONTENT_LENGTH'});}

$|=1;
$query1=$query;
if ($query eq '') {
print "<html>\n";
print "<head>\n";
print "<meta http-equiv=\"Content-Type\" content=\"text/html\; charset=windows-1251; content-coding=base64; Accept-Encoding=base64; Encoding=base64\">\n";
print "<title>Загрузка файла</title>\n";
print "<link rel=\"stylesheet\" type=\"text/css\" href=\"../style_main.css\">\n";
print "</head>\n";
print "<body>\n";
print "<form enctype=\"multipart/form-data\" method=\"POST\" action=\"upload.cgi\">\n";
print "<table border=\"0\" cellpadding=\"0\">\n";
print " <tr>\n";
print " <td><font color=\"\#0000FF\">Выберете файл:</font></td>\n";
print " <td><input type=\"file\" name=\"user_file\" ACCEPT=\"application/octet-stream\" content-coding=\"base64\" Accept-Encoding=\"base64\" Encoding=\"base64\"></td>\n";
print " </tr>\n";
print " <tr>\n";
print " <td>\ \;\n";
print " <p><input type=\"submit\" value=\"Загрузить\">\n";
print " </td>\n";
print " <td>\ \;</td>\n";
print " </tr>\n";
print "</table>\n";
print "</form>\n";
print "</body>\n";
print "</html>\n";
}
else {
if ($ENV{'CONTENT_TYPE'}=~/multipart/) {
($bound)=($ENV{'CONTENT_TYPE'}=~/boundary=(\S+)/);

@parts=split(/\n--$bound(-)*/,$query);
@parts=grep($_ ne '',@parts);
foreach (@parts) {
($header,$body)=split(/\n\s*\n/,$_,2);
$body1=$body;
($name)=(/name=\"([^\"]*)\"/);
$body=~s/\n$//;
$body=~s/\r$//;
($filename)=(/filename=\"([^\"]*)\"/);
if ($name eq 'user_file') {
@filename=split (/\\/,$filename);
$user_file=$body;
$body2=$body1;
$user_file_name=@filename[$#filename];;
}
}
}
else {}
open (FILE,">$userdir/$user_file_name");
binmode FILE;
print FILE $user_file;
close (FILE);
print "<html>\n";
print "<head>\n";
print "<meta http-equiv=\"Content-Type\" content=\"text/html\; charset=windows-1251\">\n";
print "<title>Файл отправлен</title>\n";
print "<link rel=\"stylesheet\" type=\"text/css\" href=\"../style_main.css\">\n";
print "</head>\n";
print "<body>\n";
print "<h1>Файл успешно отправлен.</h1>\n";
print "<hr>";
print "<a href=\"mailto:dmkaz\@mail.ru\"><font color=\"\#0000FF\">dmkaz\@mail.ru</font></a><br>";
print "<a href=\"http://spartak.dax.ru\"><font color=\"\#0000FF\">http://spartak.dax.ru</font></a>";
print "</body>\n";
print "</html>\n";
}



Алексей CheshireCat Иванов 2001-04-09 12:32:14


Это может быть лимит, установленный администратором веб-сервера в конфиге апача.


Наэтом дискуссия заканчивается, а проблема тем не менее не решена!!! Помогите плиз!
Дмитрий Котеров:
Отлаживать надо.
Не мучайтесь лучше, а воспользуйтесь хотя бы CGI::WebIn-ом, если так не хотите CGI.pm.
Ant:
Дело не в том каким модулем надо пользоваться, а в том, что бы вообще БЕЗ них.

Но это уже в прошлом!!! Путь найден. Код выше вообще очень запутан. Вся проблема в том, что бы разобрать входной STDIN при UPLOAD'E. Проблема в том, что стандартный вход идет не просто как пара КЛЮЧ-ЗНАЧЕНИЕ, а как я понял + еще и разделители (через STDIN проходит не только plain/text а еще multipart/form-data).

В общем я поискал на разных сайтах информацию по этому вопросу и объединил ВСЕ что нашел. В итоге вроде работает. :)

Кому надо - пользуйтесь:

В хтмл вставляем следующий код (хотя его опять же можно генерить с помощью перла - кому как нравится)

<form method="post" enctype="multipart/form-data" action="*path_to_cgi_script*">
<input type="file" name="upload_file">
<input type="submit">
</form>

Самое главное, чтобы в форме присутствовал параметр enctype="multipart/form-data". Иначе работать не будет.

Ну и создаем Perl-script:

#!/usr/bin/perl -w

print "Content-type: text/html;\n\n";

if ($ENV{'CONTENT_LENGTH'}){
$buffer = ''; binmode STDIN;
read(STDIN, $input, $ENV{'CONTENT_LENGTH'});
}

$ENV{'CONTENT_TYPE'} =~ /multipart\/form-data; boundary=(.+)$/;
$boundary = '--'.$1;

@list = split(/$boundary/, $input);

for ($num=1; $num<$#list;$num++){
$item = $list[$num]; $test = $item;
$item =~ /"([^"]+)"/;
$field_name = $1;
$field{$field_name} = $';
$field{$field_name}=~ s/\n|\r//g;
if ($test =~ /upload_file\d*/oi){ & }
}

sub upload{
$test=~ /Content-type:/i;$thingy=$`;
$thingy2=$';$thingy2 =~/\r\n\r\n|\n\n/;$conttype=$`;
if ($conttype =~ m! (\w+)/!i) {
$upload_type=$1;
$conttype =~ s! $upload_type/!!;
}
($not_required,@names) =split(/;/,$thingy);

$names[1] =~ /"([^"]+)"/;
$1 =~ /([^\\]+)$/;
$filename=$1;
$filename=~ s/ /_/g;
$filename =~ s/[-']//g;

$test=~ /\r\n\r\n/;
$file=$';


open(QQ,">$filename");
binmode QQ;
print QQ $file;
close QQ;

}

В принципе он работает (но без всяких наворотов таких как ограничение по размеру входящего файла, расширению и т.п.). Но я думаю, что это можно легко добавить если кому надо. Вообщем я урезал скрипт до минимма (что бы было понятно).

Если есть какие-то комментарии и добавления - прошу (я сам только вчера занялся этим вопросом - так что самому интересно :)).
Дмитрий Котеров:
Дело не в том каким модулем надо пользоваться, а в том, что бы вообще БЕЗ них.
Если не секрет, откуда такое жестокое ограничение?
Ant:
Ну, во-первых, модули "нагружают" программу (тот же цги сколько весит!!!), а во-вторых есть необходимость пользоваться шифровальными методами для защиты программ. А в этом случае трудно приходится с модулями... :(
Enilatiar:
"нагружают" программу (тот же цги сколько весит!!!)
А Вы знаете что запуск модуля вида
use CGI qw(:standard);
Загружает не весь модуль, а лишь избранные функции. Этим же способом можно загрузить отдельные функции, так что общий объем загруженного модуля может быть не больше вашего кода, и уж во всяком случае будет наверняка содержать меньше потенциальных ошибок и, что еще более вероятно, будет более эффективным.
Дмитрий Котеров:
Ant:
Вы бы быстродействие сначала замерили, с модулем и без. А уж потом выводы делали. Могу сказать, что один-единственный модуль почти ничего не нагружает (для сравнения, на dklab.ru их подключается десятка 3, и ничего, работает).
Ant:
Возможно, но, согласитесь, со своим набором подпрограмм намного удобнее. Хотя тут уже дело вкуса. Каждый пишет так как ему нравится!!!
Enilatiar:
но, согласитесь, со своим набором подпрограмм намного удобнее
Вам, батенька, на ассемблере надо рисовать. Если бы каждый писал "как ему нравиться", то никто не стал бы подниматься до языков высокого уровня. Впрочем, я согласен с тем, что каждый тратит свое время по мере своего понимания.
Ant:
Вообще-то КАЖДЫЙ и РИСУЕТ как ему нравится (на то мы и люди что бы отличаться друг от друга). А вот хамить не обязательно. Воистину каждый тратит свое время по мере своего понимания!!! Только не каждый задумывается над этим!
Enilatiar:
хамить не обязательно
Что Вы! Боже упаси. Простите великодушно за мои дерзкие слова. Но желания обидеть и хамства в них не было. Я лишь выразил свою точку зрения на "повторно использумый код".

P.S. Справедливости ради надо отметить, что я неосторожно выделил слово "рисовать". Но, исключительно, в целях созерцания слова. Ведь, забавный получается каламбур, рисовать - значит заниматься рисом.
Ant:
Что Вы! Боже упаси. Простите великодушно за мои дерзкие слова. Но желания обидеть и хамства в них не было. Я лишь выразил свою точку зрения на "повторно использумый код".

P.S. Справедливости ради надо отметить, что я неосторожно выделил слово "рисовать". Но, исключительно, в целях созерцания слова. Ведь, забавный получается каламбур, рисовать - значит заниматься рисом.

Ладно, простим друг друга, что бы в мире стало больше добра.

P.S. Я думаю тему можно закрыть.
Дмитрий Котеров:
...только перед этим я скажу, что Perl славен как раз своими огромными библиотеками готового кода — это его главное достоинство. Поэтому не пользоваться библиотеками — все равно, что программировать в кодах CGI-скрипты.
Ant:
Перенесено из форума: Программирование::Perl::Все в кучу.
Перенесено в форум: Программирование::Perl::Склад готовых решений.

Эта тема на forum.dklab.ru