Forum Webscript.Ru

Программирование => Perl => Тема начата: Е. Перлов от 21 Января 2003, 18:25:06

Название: file upload
Отправлено: Е. Перлов от 21 Января 2003, 18:25:06
Здрасьте
У меня такой вопрос: как перекачать на сервер файл пользователя, имя которого он ввёл в форме? То, что я нашел в perldoc не работает, а именно:


$filename = $query->param(\'uploaded_file\');
# Read a text file and print it out
while (<$filename>) {
print;
}
Название: file upload
Отправлено: NeoNox от 21 Января 2003, 19:05:52
FAQ Вечная тема - закачка файла на сервер(upload).
http://wiki.webscript.ru/PFWWWUpload
Название: file upload
Отправлено: Е. Перлов от 22 Января 2003, 21:26:18
Я запустил этот скрипт из "вечной темы"; он действительно создаёт файл в директории pics и даже с правильным размером, но просмотреть этот файл в эксплорере не удаётся. Вместо картинки появляется известный красный крестик. Даже если изменить аттрибуты файла на 666 или 777. В чём здесь может быть проблема?
Название: file upload
Отправлено: Chs от 22 Января 2003, 22:27:30
Русский апач скорее всего. Читаем ниже текста скрипта внимательно.:)
Название: file upload
Отправлено: Е. Перлов от 23 Января 2003, 00:36:15
Я не очень-то понял, о чём там (ниже текста) идёт речь. Если речь об изменении httpd.conf, то об этом и речи быть не может; ведь сервер не мой, у меня нет таких прав... И что мне делать в таком случае?
Название: file upload
Отправлено: Е. Перлов от 23 Января 2003, 04:32:49
Кстати, вы не могли бы объяснить что во что перекодируется апачем? Я так понимаю, что страдают только байты, значение которых>=128, причём изменяются они по определённому алгоритму, так?
Название: file upload
Отправлено: Mog. от 23 Января 2003, 08:36:50
Е. Перлов
Цитировать
сервер не мой

А чей? В смысле где хостишся? Если не секрет.
Название: file upload
Отправлено: Chs от 23 Января 2003, 09:16:05
Цитировать
Если речь об изменении httpd.conf, то об этом и речи быть не может; ведь сервер не мой, у меня нет таких прав... И что мне делать в таком случае?

Если .htaccess не поддерживается - менять хостинг.
Название: file upload
Отправлено: Е. Перлов от 24 Января 2003, 03:12:43
Цитировать
А чей? В смысле где хостишся? Если не секрет.

на h1.ru

Цитировать
Если .htaccess не поддерживается - менять хостинг.

а что такое .htaccess и что с ним нужно сделать чтобы мои картинки не портились при загрузке?
Название: file upload
Отправлено: NeoNox от 24 Января 2003, 11:37:42
http://www.hut.ru/instr_h3.shtml

При таком ФАКе как на h1, бежать c этого хостинга нужно быстро. ;)
Название: file upload
Отправлено: Е. Перлов от 24 Января 2003, 17:54:06
А при таких жестких правилах, как на hut.ru к ним вообще соваться не стоит: если в течении одной недели не загрузить обновления на сайт, то его удаляют :( А ФАК у них не плохой. Спасибо ;) Теперь картинки отображаются.

Но и русский текст тоже отображается правильно. Почему? :) Вообще, в какой кодировке он посылается от клиента?
Название: file upload
Отправлено: NeoNox от 24 Января 2003, 18:14:02
Цитировать
Вообще, в какой кодировке он посылается от клиента?

В какой ты предложил отправить.
Цитировать
А ФАК у них не плохой.

Так почему ты там не нашел ответ?
Название: file upload
Отправлено: Е. Перлов от 24 Января 2003, 19:21:11
Цитировать
Так почему ты там не нашел ответ?


Я же раньше не знал, что у них неплохой ФАК.

Цитировать
В какой ты предложил отправить.


А как предложить отправить русский текст в определённой кодировке? Можно ли сделать что-нибудь вроде этого:




...
Название: file upload
Отправлено: Mog. от 24 Января 2003, 19:26:03
Цитировать
Можно ли сделать что-нибудь вроде

Чудак-человек, чем на форуме спрашивать, взял да и попробовал :)
Название: file upload
Отправлено: YA от 24 Января 2003, 19:35:17
Цитировать
А как предложить отправить русский текст в определённой кодировке?
http://www.w3.org/TR/html4/interact/forms.html#h-17.3
Название: file upload
Отправлено: NeoNox от 24 Января 2003, 19:35:29

дМС ОБЮБМБ ОХЦОП HTML ЧЩХЮЙФШ!
Название: file upload
Отправлено: Е. Перлов от 24 Января 2003, 22:05:43
Цитировать
Чудак-человек, чем на форуме спрашивать, взял да и попробовал

А чё пробовать-то, у меня и так всё работает; но это не вселяет в меня слепую веру в то, что такая же работоспособность будет обеспечиваться и на других ОС.

Цитировать
http://www.w3.org/TR/html4/interact/forms.html#h-17.3

OK, thanks

Цитировать
дМС ОБЮБМБ ОХЦОП HTML ЧЩХЮЙФШ!

ЧЕУШ ЮФПМЙ?
Название: file upload
Отправлено: YA от 25 Января 2003, 09:11:29
Цитировать
ЧЕУШ ЮФПМЙ?
Именно!
Название: file upload
Отправлено: Wyclef от 05 Февраля 2003, 08:40:22
Упс :(

При попытке закачки большого файла (>1mb) через web-форму - получаю ответ "Сервер не найден", с маленькимим файлами все ок. Где ответ поискать?

Здесь в форуме пробегала тема, что можно пользоваться сокетами и чем-то там, чтобы на фтп заливать с логином и паролем), киньте примерчик.
Название: file upload
Отправлено: Chs от 05 Февраля 2003, 09:03:23
Цитировать
Здесь в форуме пробегала тема, что можно пользоваться сокетами и чем-то там, чтобы на фтп заливать с логином и паролем), киньте примерчик.

Поиск по форуму рулит.:)
Название: file upload
Отправлено: Wyclef от 05 Февраля 2003, 09:09:59
рулит то он рулит... а ответа нету...
Название: file upload
Отправлено: Chs от 05 Февраля 2003, 09:25:14
Цитировать
рулит то он рулит... а ответа нету...

Руки.:)
Искать по этому форуму. Ключевое слово ftp. Пятая строчка в списке результатов.
Название: file upload
Отправлено: Mog. от 05 Февраля 2003, 17:01:39
Цитировать
При попытке закачки большого файла (>1mb) через web-форму - получаю ответ "Сервер не найден", с маленькимим файлами все ок. Где ответ поискать?

При попытке закачки файла > 40 kb, получаю ош. 500. Ответ очевидно у тех. поддержки хостинга, т.к. тот же код на другом хостинге (таком же бесплатном) закачивает (ну как минимум 500кб, проверено ) без проблем.
Отсюда вытек вопрос, может ли хостер ограничить этот обьем?
Название: file upload
Отправлено: NeoNox от 05 Февраля 2003, 17:13:48
Если я ничего не путаю, то это может быть лимит, установленный администратором в конфиге апача.
Название: file upload
Отправлено: Wyclef от 05 Февраля 2003, 22:50:03
Цитировать
Руки.
Искать по этому форуму. Ключевое слово ftp. Пятая строчка в списке результатов.


Глаза.:)
Ладно, но чего-то там бред какой-то... Забыли.

Вы мне вот, что скажите - меня конкретно интерисует такой механизм, реализУем или нет:

1. Есть multipart веб-форма для закачки.
2. Я делаю обзор, выбираю файл, посылаю.
3. Скрипт быстро это дело принимает, делает редирект куда-то (просто на др. URL - я могу уйти с него, закрыть браузер и т.д.)
4. Я иду пить чай или занимаюсь чем-то еще:), а в это время выбранный файл закачивается на сервер.

PLZ, Поверните меня в нужную сторону и давайте обсудим на пальцах... А то все чета вокруг до около, примеры бы какие...
Название: file upload
Отправлено: NeoNox от 06 Февраля 2003, 11:11:01
Цитировать
3. Скрипт быстро это дело принимает, делает редирект куда-то (просто на др. URL - я могу уйти с него, закрыть браузер и т.д.)
4. Я иду пить чай или занимаюсь чем-то еще, а в это время выбранный файл закачивается на сервер.

Реализуем, только грабли расчищать будешь сам.
Точнее грабель не так уж много...
нужная сторона - perldoc -f fork
Название: file upload
Отправлено: Wyclef от 06 Февраля 2003, 16:24:36
Почему не загружались большие файлы вроде выяснил:

В .htaccess было прописано:
LimitRequestBody 131072

В логах сервера нарыл следующую запись:
... Request content-length of 1278353 is larger than the configured limit of 131072

Изменил на большее значение - файл закачался, но скрипт застревает на странице с формой пока не примет все данные, а только потом редиректит на др. адрес - соответственно пункт 3 не выполняется.

Цитировать
perldoc -f fork

Использовал код с fork-ом, но у меня подозрение, что он тут ни при чем... Код приведу в порядок и выложу чуть позже.
Название: file upload
Отправлено: Wyclef от 06 Февраля 2003, 18:08:22
Вот собсно:

загрузка -> редирект

а редирект -> загрузка? (вот в чем вопрос...)

upfile.pl


#!/usr/bin/perl
use strict;
use CGI qw(:standard);
my $Query = new CGI;
my $remote_path = \'/home/user/WWW/upload\';
my $success_url = \'success.html\';
my $local_path = $Query->param(\'upload\');
my $pid = fork();
if ($pid) {
print $Query->redirect( -url => $success_url );
wait;
exit 0;
} else {
$| = 1;
die "Cannot fork $!" unless defined $pid;
upload_file($remote_path.\'/\'.extract_name($local_path));
exit;
}

########################################
sub upload_file {
my $path = shift or return;
my $bytes;
my $buffer;
open F, ">$path" or die "Cannot open $path for writing\\n";
flock F, 2;
binmode F;
while ($bytes = read($local_path, $buffer, 4096)) {
print F $buffer;
}
die "Error reading uploaded file\\n" unless defined $bytes;
close F;
}

########################################
sub extract_name {
my $path = shift or die "Nothing to upload\\n";
$path = reverse $path;
$path =~ /([^\\\\\\/\\:]*)/;
$path = reverse $1;
return $path;
}


В коде: $path =~ /([^/:]*)/; исправить на: $path =~ /([^\\\\\\/\\:]*)/;

Форма



Upload








Название: file upload
Отправлено: Mog. от 06 Февраля 2003, 18:59:48
Вопрос спецам
Скрипт вызываемый методом ПОСТ запускается до того, как сервер получает весь запрос с телом, после приема всего запроса, после приема только заголовка запроса (еще варианты)?
Название: file upload
Отправлено: Wyclef от 09 Февраля 2003, 00:21:04
И тишина... :(

Я так думаю организовать редирект до загрузки файла невозможно, т.е. только получил, переправил.

Есть идеи?

З.Ы. а в коде можно и без fork\'a обойтись.
Название: file upload
Отправлено: NeoNox от 10 Февраля 2003, 11:14:38
Цитировать
Я так думаю организовать редирект до загрузки файла невозможно

Возможно.
Вечером до машины доберусь - отвечу.
Название: file upload
Отправлено: Wyclef от 11 Февраля 2003, 20:38:33
Жду с нетерпением :)
Название: file upload
Отправлено: NeoNox от 14 Февраля 2003, 13:37:09
Wyclef
Ты просто не до конца понял зачем нам нужно форкнуться.

Вот что нужно было сделать:
my $local_path = $Query->param(\'upload\');

my $pid = fork();

print $Query->redirect( -url => $success_url ); #(!)

if ($pid) {

#  sleep(10);  #Это для проверки - засыпаем и в это время мы уже на success.html
                     # но файл еще не загружен

    upload_file($remote_path.\'/\'.extract_name($local_path)); #(!)
    wait;
    exit 0;
} else {
    $| = 1;
    die "Cannot fork $!" unless defined $pid;
    exit;
}
Название: file upload
Отправлено: Wyclef от 14 Февраля 2003, 17:25:42
Код работает идентчно...

Что-то не то... Как я понял:

if ($pid) {
   # родитель
   ...
} else {
   # потомок
   ...
}

По логике родитель должен быстро завершиться, а потомок продолжать работать? Такое возможно? Что-то я в механизме запутался... :confused:
Название: file upload
Отправлено: NeoNox от 14 Февраля 2003, 17:41:48
Ты sllep(10) расскоменть и все станет понятно.
Более наглядно обьяснить не могу :)
Цитировать
if ($pid) {
# родитель

Нет, эта ветка (вся) принадлежит потомку.
Название: file upload
Отправлено: Wyclef от 14 Февраля 2003, 18:03:27
Цитировать
Ты sllep(10) расскоменть и все станет понятно.


Я уже несколько вариантов препробовал, сначала свой код мучал, потом с твоими правками - предварительного редиректа не добился... Может суть в реализации CGI?

Да, и если честно прихожу к выводу, что моя идея с редиректом не совсем правильная и правомерная...

А fork тема интересная - как вы считаете? :)

Возможно fork просто не применим в данном (конкретном) случае...

Короче, обложился книгами, изучаю - может получится выродить что-нибудь более аргументированное...
Название: file upload
Отправлено: NeoNox от 14 Февраля 2003, 18:12:10
/шепотом/ Какая операционка?
Название: file upload
Отправлено: Wyclef от 14 Февраля 2003, 18:16:31
FreeBSD
Название: file upload
Отправлено: NeoNox от 14 Февраля 2003, 18:52:14
Тогда не понимаю.
Во вложениях мой вариант.
У меня он 100% работает,
поправь на свои пути и пробуй.
#!/usr/bin/perl -w


use strict;
use CGI qw(:standard);
use CGI::Carp qw(carpout fatalsToBrowser);

my $Query = new CGI;
my $remote_path = \'/home/EMU/tmp\'; #заменить на свой путь
my $success_url = \'./index.html\';  #заменить на свой путь

my $local_path = $Query->param(\'upload\');

if ($local_path){

print $Query->redirect( -url => $success_url );

my $pid = fork();

if ($pid) {

sleep(10);

upload_file($remote_path.\'/\'.extract_name($local_path));

wait;

exit 0;

} else {

$| = 1;

die "Cannot fork $!" unless defined $pid;

exit;

}



}else{

print &index();

}


########################################

sub upload_file {

    my $path = shift or return;

    my $bytes;

    my $buffer;

    open F, ">$path" or die "Cannot open $path for writing\\n";

    flock F, 2;

    binmode F;

    while ($bytes = read($local_path, $buffer, 4096)) {

        print F $buffer;

    }

    die "Error reading uploaded file\\n" unless defined $bytes;

    close F;

}



########################################

sub extract_name {

    my $path = shift or die "Nothing to upload\\n";

    $path = reverse $path;

    $path =~ /([^\\/:]*)/;

    $path = reverse $1;

    return $path;

}

sub index{
print header();

print qq~
 
 
   Upload
 
 





 
 
~;
}
Название: file upload
Отправлено: Wyclef от 16 Февраля 2003, 00:14:21
По идее должно работать, но... нет.

В IE когда нажимаю на кнопку, идет коннект, в статус-баре начинает прибавляться "синий прямоугольник" т.е. пошла закачка (у Opera пишется "Uploading file(s) to server"), на экране остается форма, только потом через n минут редиректит (когда объем отосланных данных чуть >= размеру файла).

Проверял, на паре серверов - одно и то же... Даже один free зарегил (http://wyclef.netfirms.com/cgi-bin/test.pl - здесь твой код).

Ты случаем не на выделенке сидишь? Может просто у тебя так быстро закачивается (хотя речь шла о метровых файлах) ;)

В любом случае, спасибо за помощь!

З.Ы. Лишний повод порыться в доках никогда не помешает :)
Название: file upload
Отправлено: Mog. от 17 Февраля 2003, 08:08:57
Цитировать
По идее должно работать

Почему?
Насколько я это понимаю, сначала запрос получает сервер. А если запрос большой (т.е. в теле запроса мегабайтный файл), сервер получает его долго (размер/скорость>=время). А после получения запроса, сервер формирует  переменные окружения и запускает скрипт. И только после этого скрипт извлекает из переменных "файл", записывает его по нужному пути, на что уходит гораздо меньше времени, чем на запрос (если конечно речь идет о модемном соединении, хотя бы с одной стороны). Поэтому fork бесполезен. А редирект можно сделать запросто, при этом скрипт то продолжает работу. Т.е. можно менять местами процессы "сохранение файла" и "редирект юзера", но поменять местами "получение запроса сервером" и "работа запрашиваемого скрипта" - это вряд ли.
ИМХО