Большой Воронежский Форум
» Программирование>Нужна помошь в решении задачи
niagara 22:34 21.02.2006
Уважаемай друзья, у меня тут возникла одна проблема не могу понять что надо сделать что бы документ выводился не в потоке данных а загружался на машину клиента при эмитации запроса.
Сейчас пойдут текста скриптов и так далее все что с этим связано.
Код#!/usr/bin/perl
# Это сам скрипт вызываеться вот так http://access.kz/get_new.pl?file=78 [Другие параметры беруться из базы т.е. в примере идут след документы 77 а также 79]
$ROOTDIR = "$ENV{'DOCUMENT_ROOT'}";
$HOST = "http://$ENV{'HTTP_HOST'}";
&obrabotka;
open(FILE,"$ROOTDIR/data/test.db");
@ARR = <FILE>;
close(FILE);
foreach $line (@ARR)
{
@scr = split(/\|/,$line);
if ($scr[0] eq $FORM{'file'})
{
$url = "$scr[1]";
}
}
$PATH = "$HOST/$url";
use LWP;
use LWP::MediaTypes qw(guess_media_type);
use CGI qw(header);
my $browser = LWP::UserAgent->new;
$user = "login";
$pass = "pass";
$area = "Input password";
$browser->credentials( # add this to our $browser 's "key ring"
"$ENV{'HTTP_HOST'}:80",
$area,
$user => $pass
);
my $url =$PATH;
my $response = $browser->get($url);
$type = guess_media_type($url);
binmode(STDOUT);
die "Error: ", $response->header($area) ||
'Error accessing', # ('WWW-Authenticate' is the realm-name)
"\n ", $response->status_line, "\n at $url\n Aborting"
unless $response->is_success;
print "Content-type: $type\n\n";
print $response->content;
################################################## ###############################
sub obrabotka
{
################################################## ##########
if ($ENV{'CONTENT_TYPE'} =~ m#^multipart/form-data#) {
if ($ENV{'REQUEST_METHOD'} ne 'POST') {
print "Invalid request method for multipart/form-data\n"; exit;
}
$maxstep=int($ENV{'CONTENT_LENGTH'});
binmode(STDIN); seek(STDIN,0,0); $lenbuf=0;
while(1) {
$buffer1=""; read(STDIN,$buffer1,8192);
$lenbuf=$lenbuf+length($buffer1); $buffer="$buffer$buffer1";
if ($lenbuf>=$maxstep) {goto("nextbuf");}
}
nextbuf:
($boundary) = $ENV{'CONTENT_TYPE'} =~ /boundary="([^"]+)"/; #"; # find boundary
($boundary) = $ENV{'CONTENT_TYPE'} =~ /boundary=(\S+)/ unless $boundary;
$temp="--$boundary--\x0D\x0A";$boundary = "--" . $boundary . "\x0D\x0A";
$buffer=substr($buffer,0,index($buffer,$temp));
@pairs=split(/$boundary/, $buffer); $lenpairs=@pairs;
for ($i=1;$i<$lenpairs;$i++) {
$pairs[$i]= substr($pairs[$i], 0, length($pairs[$i])-2);
$pozition=index($pairs[$i],"\r\n\r\n");
$header= substr($pairs[$i], 0, $pozition);
($cd) = grep (/^\s*Content-Disposition:/i, $header);
($name) = $cd =~ /\bname="([^"]+)"/i;
($name) = $cd =~ /\bname=([^\s:;]+)/i unless defined $name;
($fname) = $cd =~ /\bfilename="([^"]*)"/i;
($fname) = $cd =~ /\bfilename=([^\s:;]+)/i unless defined $fname;
$fname=substr($fname,rindex($fname,"\\")+1);
$value= substr($pairs[$i], $pozition+4);
if ($fname or $header =~ /Content-Type:/i) {
if ($header =~ /Content-Type:\s+([\w, \-, \\, \/]+)/i and $fname) {
$fname=~ s/([\w-]+ \.)//i; #?????? ???, ???? ????????????
$FORM{$name}=$fname;
$FORM{"src$name"}=$value;
$FORM{"ct$name"}=$1;
} else {$FORM{$name}=""}
} else {$value =~ s/\x0D\x0A/\x0A/g;$FORM{$name}=$value}
}
}
else {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
if (!$buffer) {$buffer=$ENV{'QUERY_STRING'};}
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/\x0D\x0A/\x0A/g;
$FORM{$name} = $value;}
}
$temp=$ENV{'QUERY_STRING'};
@pairs=split(/&/,$temp);
foreach $item(@pairs) {
($key,$content)=split (/=/,$item,2);
$content=~tr/+/ /;
$content=~ s/%(..)/pack("c",hex($1))/ge;
$FORM{$key}=$content;
}
}
################################################## ###############################
Скрипт самой базы
откуда беруться докумены после получения запроса имя вайла test.db
Код
ID|path|
79|data/faq/avatar/79.gif|
77|data/faq/avatar/77.zip|
78|data/faq/avatar/akcii.txt|
Это настройки htaccess для директории где лежат все документы. При помощи его мы ограничиваем доступ к документам.
Код
AuthName "Input password"
AuthType Basic
AuthUserFile "z:/home/access.kz/www/data/.htpasswd"
require valid-user
Ну вроде надеюсь ничего не упустил из основных блоков..
Так вот как вы наверно можите видеть данный процес позволяет просмотреть документы
Задача вот какая Надо сделать так что бы пользователь авторизовался через скрипт и ему предлагалось загрузить документ сеебе на компьютер так же как бы и не было авторизации. Проблема в том что данный механизм позволяет только просматривать без проблем текущие документы.
Но как заставить загрузиться документу.. ума не приложу.. надеюсь на то что вы сможите мне помочь с решением этой задачи..
Или подскажите альтернативное решение данного. [Ответ]
Ant0 00:28 02.03.2006
Если я правельно тебя понял, то тебе нужно отдать файло клиенту c помощью перла?...
Если да: то тебе надо сначала бровзеру скормить заголовок что ты шлешь бинарные данные, а потом данные - спецификацию сматри по HTTP1.0(1)

Если хочешь посматреть на сырцы, то на Сях рекомендую - thttpd или httpd (встроенный в busybox)
На перле глянь на webmin
На чистом шелле даже проскакивал мини-веб-сервер (убей не помню как его звать) - но принцип более чем


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

А вот извращаться с веб-сервером я бы не советовал - гемору много.... да и привязываешься к конкретному серверу....
[Ответ]
maximn 00:49 02.03.2006
гы. не видел этой темы =)

насколько я вижу, скрипт посылает контент тайп:

Сообщение от :
print "Content-type: $type\n\n";
print $response->content;

причем контент тайп верный:

Сообщение от :
$type = guess_media_type($url);

поэтому браузер и открывает документ самостоятельно. rfc 1521 рекомендует для "неизвестных" типов посылать "application/octet-stream". логика простая - браузер не поймет что это и предложит банально сохранить файл.

другими словами, замени
print "Content-type: $type\n\n";
на
print "Content-type: application/octet-stream\n\n"; [Ответ]
Ant0 00:56 02.03.2006
Ага! Вот про это я и говорю....
Но все таки афтару почитать документацию стоит! - много вопросов отпадет [Ответ]
Вверх