LINUX.ORG.RU

Вопрос по CGI


0

0

Можно ли с помощью CGI-скрипта на Perl организовать закачку файлов на сервер. Т.е. указываем в строке полное имя локального файла, нажимаем "Отправить" и он закачивается в определенную директорию на сервере? Как это реализовать?

anonymous

делать так:

apache должен быть настроен так, чтобы не перекодирует данные POST(иначе работать не будет):

#!/usr/bin/perl -w
$basedir = "/usr/home/vovka/public_html/files";
$donepage = "http://www.myserver.ru/~vovka/files";;
use CGI; 
$onnum = 1;
while ($onnum != 9) {
	my $req = new CGI; 
	my $file = $req->param("FILE$onnum"); 
	if ($file ne "") {
		my $fileName = $file; 
		$fileName =~ s!^.*(\\|\/)!!; 
		$newmain = $fileName;
		open (OUTFILE, ">$basedir/$fileName"); 
		while (my $bytesread = read($file, my $buffer, 1024)) { 
			print OUTFILE $buffer; 
		} 
		close (OUTFILE); 
	}
	$onnum++;
}
print "Content-type: text/html\n";
print "Location:$donepage\n\n";

Соответственно указывая число в цикле while ($onnum != 9) можно 
подгружать нужное чилсо файлов при одном POST запросе. html-код 
формы для скрипта такой:

<form method="POST" action="/cgi-bin/fup.pl"
ENCTYPE="multipart/form-data">
File 1: <input type="file" name="FILE1">
<br>File 2: <input type="file" name="FILE2">
<br>File 3: <input type="file" name="FILE3">
<br>File 4: <input type="file" name="FILE4">
<br>File 5: <input type="file" name="FILE5">
<br>File 6: <input type="file" name="FILE6">
<br>File 7: <input type="file" name="FILE7">
<br>File 8: <input type="file" name="FILE8">
<br>File 9: <input type="file" name="FILE9">
<br>
<input type="submit" value="Upload!">
</form>

Пакеты вида multipart/form-data описываются rfc1867

vilfred ☆☆
()
Ответ на: комментарий от vilfred

не забудь про ограничение на размер файла, 10 мег так не на всякий сервак зальешь, и не со всякого браузера.

и еще я не понял, где данные раскодируются. обычно же POST файла заBASE64ется или еще как.

и что такое $newmain?

anonymous
()
Ответ на: комментарий от vilfred

>apache должен быть настроен так, чтобы не перекодирует данные POST
Это где и что?

anonymous
()
Ответ на: комментарий от anonymous

1024 = это мег, это значит, что максимальный файл который может загружаться - 1 мег, соответственно 10 мегабайтам сответствует число 10240. Только если скорость связи 10 кил в секунду, то придется ждать. И непонятно порвалась связи или нет.

$newmain это осталось от какого-то скрипта, уткуда выдрано подгружение файлов... В конфиге апача есть где-то настройка которая коворит, перекодировать ли данные пост как URI GET строку. Т.к. тут бинарные данные могут сливатся, то декодировать не надо. А как выключить в конфиге апача декодирование multipatr/form-data пакетов я щас вспомнить не смог. Яндекс пишет, что это можно сделать при компиляции апача там опция какая-то есть. Яже с РПМников работел, потому таких проблем с отключением декодирования в апаче не имел... Короче, оно файл тебе подгрузит, но это будет уже перекодированный файл.

vilfred ☆☆
()
Ответ на: комментарий от vilfred

Короче скрипт отрабатывает (на удаленном компе страничка $donepage показывается), но на сервере файла не появляется. Пробовал с разными файлами, все менее 50 кб. Я так понимаю вся загвоздка в этой настройке апача, которая непонятно как изменяется. Я в тупике. Необходимо реализовать передачу файлов на сервер только средствами http со стороны клиента.

anonymous
()
Ответ на: комментарий от anonymous

У тебя, по видимому, нет каких-то прав, файл при неправильной 
обработке апачем запроса POST должен появляться, но плохой файл, 
например если подгружаешь хороший jpeg, он после подгрузки 
перестает показываться в программе просмотра. 

Что я делал, чтобы запустить этот скрипт

для перлового скрипта

 1001  cd /var/www/cgi-bin/
 1002  joe upload.pl
 1003  chmod 755 upload.pl

для html скрипта:

 1001  cd /var/www/html
 1002  mkdir uploads
 1003  chown apache:apache uploads/
 1004  w
 1005  joe upload.html

И смотри логи tail -f /var/log/httpd.access или 
tail -f /var/log/httpd.error или как они у тебя называются.

И еще, возможно, расширение перлового скрипта нужно изменить 
на *.cgi, т.к. возможно, некоторые апачи не понимают *.pl но понимают *.cgi

vilfred ☆☆
()
Ответ на: комментарий от vilfred

> Короче, оно файл тебе подгрузит, но это будет уже перекодированный файл.

мне кажется что честнее будеть добавить к скрипту пару строчек раскодирующих base64 или что там используется, чем рассуждать о
настройках апача, бывают ведь всякие хостинги, не везде ты root.
я в перле не силен, но думаю наверняка в cpan для этого модуль есть.

anonymous
()
Ответ на: комментарий от vilfred

Ура! Наконец-то я нашел ошибку.
$ tail -f /var/log/httpd.error
Name "main::newmain" used only once: possible typo at /var/www/cgi-bin/upload.cgi line 13.
Use of uninitialized value in string ne at /var/www/cgi-bin/upload.cgi line 9.

"Use of uninitialized value in string ne at /var/www/cgi-bin/upload.cgi line 9." это на строке

if ( $file ne "" )

т.е $file была uninitialized, т.е. NULL (или что там в Perl вместо этого)
А предыдущая строка:

$file=$req->param("FILE");

И тут я подумал, а вдруг черт возьми я в форме вместо FILE написал FILE1 (начал писать твой скрипт, но потом решил упростить до одного файла за один POST, а циферку не затер). И так оно и оказалось.

Всё, теперь все работает как надо. Проверял правда пока локально, завтра потестирую удаленно.
Спасибо за скрипт.

ЗЫ Ещё говорят полезно делать binmode OUTFILE перед чтением/записью если файл отсылается из винды.


anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.