Ошибка: Failed to parse the Currency Converter XML document.
$33 666.91


Ошибка: Failed to parse the Currency Converter XML document.
$47 695.16


Ошибка: Failed to parse the Currency Converter XML document.
$20 004.13


FAQ по разделу CGI интерфейс

Как мне сделать аутентификацию на Перле, а не средствами веб-сервера?:
Для того, чтобы браузер выдал запрос логина и пароля, скрипт должен выдать следующие заголовки:
print «WWW-Authenticate: Basic realm=\"что то там\"\n»;
print «Status: 401 Unauthorized\n\n»;
print «Ошибка авторизации!\n»;
При этом «что то там» — это имя области авторизации, по правилам для области с одним именем должен всегда срабарывать один и тот же пароль. Проблема заключается в том, что ответ пользователя сидит в заголовке HTTP-запроса, в поле Authorization, которое скрипту через переменные окружения не передаётся. Для сервера Апаче эта проблема решается прописыванием в файле конфигурации следующих строк:

RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) — [E=HTTP_CGI_AUTHORIZATION:%1]
Всё что он делает — это добавляет в переменную окружения HTTP_CGI_AUTHORIZATION, в которую пишется содержимое HTTP заголовка Authorization, таким образом означенное поле становится доступным для анализа внутри скрипта. Формат этого поля следующий: «login:password», причём эта строка закодирована в Base64, получить эти составляющие можно так:

use MIME::Base64;
$ENV{HTTP_CGI_AUTHORIZATION} =~ s/basic\s+//i;
($REMOTE_USER,$REMOTE_PASSWD) =
split(/:/,decode_base64($ENV{HTTP_CGI_AUTHORIZATION}));
Вот простейший скрипт, проверяющий авторизацию. В качестве «правильных значений» используются:
Login — «user»
Password — «userpas»
use MIME::Base64;
$ENV{HTTP_CGI_AUTHORIZATION} =~ s/basic\s+//i;
($REMOTE_USER,$REMOTE_PASSWD) =
split(/:/,decode_base64($ENV{HTTP_CGI_AUTHORIZATION}));

# проверяем значения $REMOTE_USER и $REMOTE_PASSWD
if (!UserAccess($REMOTE_USER,$REMOTE_PASSWD)) {
print «WWW-Authenticate: Basic realm=\"что то там\"\n»;
print «Status: 401 Unauthorized\n\n»;
print «Ошибка авторизации!\n»;
exit;
}

# код, который выполняется при успешной авторизации
print «Content-type: text/html\n\n»;
print «Привет, $REMOTE_USER!»;
exit;

# простейшая проверка:
# совпадают ли введенные значения с «user» и «userpas»
sub UserAccess {
my $aUser = $_[0];
my $aPass = $_[1];

$res = ( $aUser eq «user» && $aPass eq «userpas» ? 1 : 0);
return $res;
}
Замечание:
=========
Если Вы работаете под ОС Windows и используете Apache для Windows, Вам нужно, для загрузки модуля Rewrite, раскомментировать в файле httpd.conf строку:
LoadModule rewrite_module modules/ApacheModuleRewrite.dll

Я пытаюсть скриптом вывести картинку, а мне вместо нее выдается стандартная битая картинка браузера.:
В этом есть две причины, во-первых необходимо выдавать правильные заголовки, во-вторых на некоторых веб-серверах необходимо переводить потоки ввода-вывода в бинарный режим, лучше это делать всегда. Если Вы берете файл из картинки, можете воспользоваться следующим примером:
print «Content-type: image/gif\n»;
# Для JPEG будет image/jpeg
print «Content-length: 7256\n\n»;
open (IMG,«image.gif»);
binmode IMG;
binmode STDOUT;
print;
close (IMG);
Заголовок Content-length в принципе необязателен, но желателен. Он должен содержать реальный размер файла в байтах. Его можно получить воспользовавшись конструкцией -s

Как сделать upload картинки через форму?:
В случае, если вам не претит воспользоваться модулем CGI, это будет выглядеть примерно так:
use CGI qw/:standard/;

# Код для HTML-формы
print «Content-Type: text/html\n\n»;
print «
»;
print « »;
print « »;
print «
»;

#end of print form

insert_image() if (param());

sub insert_image {
# путь к директории для закачки директория
# должна иметь право на запись для
# пользователя, под которым работает веб-сервер
my $downpath = «tmp/»;

my $in=param(«picture»);

# выделяем имя файла из параметра
my ($name) = $in =~ m#([^\/:]+)$#;

open(OUT,«>$downpath$name»);
binmode(OUT);
# читаем входной поток и пишем в файл
while () {
print OUT $_;
}
close(OUT);

# выводим надпись о закачке файла
print «Upload file: $name»;
}
Замечание:
Часто возникает проблема: «При закачке картинок 00 меняется на 20(пробел), соответственно картинка не смотрится...»

Это следствие перекодирования http-сервером принимаемых данных.

Если у Вас русский Apache, то эта проблема «лечится» выставлением директивы:
CharsetRecodeMultipartForms off

Как получить документ с другого сервера с помощью perl-сценария?:
Воспользуйтесь модулем LWP (Library for WWW accesss in Perl).

#!/usr/bin/perl
use LWP;
$au=LWP::UserAgent->new();
$au->agent(«PerlAU/0.1»);

$url=«http://askme.webclub.ru»;
$document=$au->request(HTTP::Request->new(GET=>$url));
if ($document->is_success) {
print «Content-type: text/html\n\n»;
print $document->content;
} else {
print «Content-type: text/html\n\n»;
print «Couldn«t fetch $url\n»;
}
Второй вариант решения:
=====================
Использовать соединение через Socket:

#!/usr/bin/perl
print «Content-type: text/html\n\n»;

$host = «askme.webclub.ru»;
$port = «80»;
$document=«http://askme.webclub.ru»;

use IO::Socket;
$remote=IO::Socket::INET->new(«$host:$port»);
unless ($remote) {die «can»t connect to http demon on $host at port $port: $!»}
$remote->autoflush(1);
print $remote «GET $document HTTP/1.0\n\n»;
while () {print}
close $remote;
Замечание:
=========
Учтите! В этом случае Вы получите ответ сервера полностью, включая HTTP заголовок ответа!

Как мне отправить POST запрос из моего perl-сценария в другую CGI-программу?:
Для отправки данных стоит восполльзоваться модулем LWP (Library for WWW accesss in Perl).

Большинство модулей в этой библиотеке являются объектно-ориентированными. Эмулируемый Агент пользователя, посланные запросы и ответы, полученные от сервера WWW, представлены объектами.

Вариант 1
========
Пусть мы хотим послать запрос в скрипт endpost.cgi следующего вида:

endpost.cgi — принимающий запрос скрипт
#!/usr/bin/perl
use CGI «:standart»;
$query=CGI->new();
print «Content-type: text/html\n\n»;
if ($query->param(«login») && $query->param(«passwd»)) {
if ($query->param(«login») eq «gorynych» &&

$query->param(«passwd») eq «gorynych») {
print «данные успешно переданы!»;
exit;
}
}
$text = $query->param(«text»);
print << «EOF»;
Укажите правильный псевдоним и пароль для передачи!

Введите текст:     
Введите псевдоним:     
Введите пароль:     

EOF

#end
post.cgi — посылающий запрос скрипт
#!/usr/bin/perl
$text = StrEscaped(«Есть многое на свете, друг Гораций,
что и не снилось нашим мудрецам!»);
$url = «http://your.host.com/cgi-bin/endpost.cgi»;
$passwd = «gorynych»;
$login = «gorynyc»;

# создадим нового Агента пользователя
use LWP::UserAgent;
$ua = LWP::UserAgent->new;

my $req = HTTP::Request->new(POST=>$url);
# указываем тип контекста
$req->content_type(«application/x-www-form-urlencoded»);
# вводим сам контекст для передачи
$req->content(«text=$text&login=gorynych&passwd=gorynych»);
my $res = $ua->request($req);

# получаем ответ от выводим его
print «Content-type: text/html\n\n»;
print $res->content;
# если вы хотите получить полный ответ, с заголовком HTTP,
# воспользуйтесь вызовом print $res->as_string

# вспомогательные процедуры
sub StrEscaped {
# используем эту процедуру для преобразования
# передаваемых символов кириллицы
my ($str)=@_;
$str=~s/([^0-9A-Za-z\?&=:;])/sprintf(«%%%x», ord())/eg;
return $str
}
Вариант 2
========
Пусть Вам нужно отправить псевдоним и пароль в некую CGI программу, которая проверяет переданные значения и возвращает 1 в случае успеха и 0 при вводе некоректных значений.

Модифицируем наш сценарий:

1. добавим в начало разбор параметров
use CGI «:standart»;
$query = CGI->new();
# если были переданы POST параметры «login» и «passwd»
# заносим их в соответствующие переменные
if ($query->param(«login») && $query->param(«passwd»)) {
$login=$query->param(«login»);
$passwd=$query->param(«passwd»);
}
# вводим значения, если переменные неопределенны
$passwd = «user» unless $login;
$login = «passwd» unless $passwd;

use LWP::UserAgent;
$ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(POST=>$url);
$req->content_type(«application/x-www-form-urlencoded»);
$req->content(«text=$text&login=$login&passwd=$passwd»);
my $res = $ua->request($req);
...вместо того, чтобы выводить контекст ответа, мы будем его проверять:
$res = $res->content;
if ($res eq 1) {
print «данные успешно переданы!»;
} else {
# возвращаем текст в читаемый вид
# и выводим форму для ввода, указывая в качестве
# принимающего сценария наш новый post.cgi
$text = StrUnescaped($text);
print << «EOF»;
Укажите правильный псевдоним и пароль для передачи!

Введите текст:     
Введите псевдоним:     
Введите пароль:     

EOF

#end
}

sub StrUnescaped {
my ($str)=@_;
$str =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack(«C», hex())/eg;
return $str
}Замечание:
=========
«Ленивые люди» используют модуль HTTP::Request::Common, для отправки POST запроса (он сам оперирует заголовками и преобразованием символов и использует предустановленный content_type).

Это выглядит так:
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
$ua = LWP::UserAgent->new;
my $req = POST $url,
[ text => «$text»,
login => «$login»,
passwd => «$passwd»
];

Вторая cookie не передается, что неправильно я сделал?:

Если вы используете библиотеку CGI.pm и функции hedaer(), redirect() из нее, то учтите, что вызов процедуры header — означает выдачу заголовка HTTP, который заканчивается комбинацией \n\n, означающей конец заголовка.

Пример:
my $c_login=cookie(-NAME=>«login», -VALUE=>$l);
my $c_passwd=cookie(-NAME=>«password»,-VALUE=>$p);

print(«Location: /cgi-bin/script.cgi\n\n»);
print header(-COOKIE=>$c_login);
# вторая кука не поставиться!
print header(-COOKIE=>$c_passwd);
Если уж Вы так хотите писать, используя CGI.pm, то пишите:
use CGI qw(:cgi);
...

$c1 = cookie( -NAME => «one»,
-VALUE => «value1»,
-EXPIRES => «+1M»
);
$c2 = cookie( -NAME => «two»,
-VALUE => «value2»,
-EXPIRES => «+1M»
);

$redirect = «/cgi-bin/script.cgi»;

print redirect( -URL => $redirect,
-COOKIE => [$c1, $c2]
);
Результат, выдаваемый сервером, будет таким:
-----------------------
Status: 302 Moved
Set-Cookie: one=value1; path=/; expires=Sat, 24-Feb — 2001 09:21:43 GMT
Set-Cookie: two=value2; path=/; expires=Sat, 24-Feb — 2001 09:21:43 GMT
Date: Thu, 25 Jan 2001 09:21:43 GMT
location: /cgi-bin/script.cgi

 

Интересное

«Резиновая вёрстка»:...
Я недавно столкнулся с задачей, в которой надо было создать двухколоночный макет страницы с «шапкой» и «подвалом», причём в коде страницы контент должен был быть расположен перед блоком...
Подробнее...
Что выбрать: Vista x86 или...
Многие пользователи задают и себе и нам вопрос, какую редакцию Windows Vista выбрать: 32-битную или 64-битную? Что ж, попытаемся ответить на данный вопрос и определить плюсы и минусы каждого...
Подробнее...
Запуск несколкьих...
Введение: Virtual Server 2005 R2 позволяет размещать на сервере гостевые операционные системы. При работе с несколькими виртуальными машинами могут возникнуть некоторые сложности.Мы вам уже...
Подробнее...
Установка Windows
Как поставить XP? Есть несколько способов. Во-первых, если ваш CD с дистрибутивом похож на тот, что выпускается Microsoft, то он должен быть бутовым (загрузочным). Чтобы загрузиться с него надо в...
Подробнее...
Секреты Delphi. Мониторинг...
Не секрет, что приложения баз данных составляют довольно большую долю всех вновь разрабатываемых приложений. Ни одна информационная система не может быть создана без соединения к той или иной...
Подробнее...
Основы позиционирования блоков
Блоки — прямоугольные области, используемые в CSS для формирования и отображения документов. Это упрощенно, очень сильно упрощенно, но для начала вполне может и хватить.С появлением нового...
Подробнее...
Электронные рассылки
Электронные рассылки — самый мощный способ продвижения своего узла.Однако, этот способ требует наибольшей аккуратности использования.Этика, оптимальный объем и содержание Регулярные рассылки...
Подробнее...
Serv-U: Установка FTP-сервера
Хочу установить на своей машине в локальной сети FTP-сервер, но не выбрал программу. Какую именно вы посоветуете и каким образом ее нужно настроить?Выбор программы Спрос рождает предложение,...
Подробнее...
Открытие XP Pro x64
Как энтузиаст новых технологий, я с нетерпением ждал возможности запустить на своем настольном компьютере Windows XP Professional x64 Edition. Недавно я собрал новую машину с процессором AMD...
Подробнее...
Java-приложение: заглянем...
Чтобы отладить приложение, можно поступить по-разному. Во-первых, можно воспользоваться штатным отладчиком из какого-либо программного пакета. Во-вторых, можно самостоятельно вычислить ошибку...
Подробнее...