Создание серверных приложений на языке PERL

       

Работа с Cookie



Работа с Cookie

(отрывок из статьи "Что такое Cookies и с чем их едят")

Что такое cookie?

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

Cookie это небольшая порция информации, которую сервер передает клиенту. Клиент (броузер) будет хранить эту информацию и передавать ее серверу с каждым запросом как часть HTTP заголовка. Некоторые cookie хранятся только в течение одной сессии, они удаляются после закрытия броузера. Другие, установленные на некоторый период времени, записываются в файл. Обычно этот файл называется 'cookie.txt'.

Что можно делать с помощью cookie?

Сами по себе cookies не могут делать ничего, это только лишь некоторая информация. Однако, сервер может на содержащуюся в cookies информацию. Например, в случае авторизованного доступа к чему либо через WWW, в cookies сохраняется login и password в течение сессии, что позволяет не вводить их при запросе каждого запаролированного документа. Другой пример: cookies могут использоваться для построения персонализированных страниц. Чаще всего встречается такое - на некотором сервере Вас просят ввести свое имя, и каждый раз, когда Вы заходите на первую страницу этого сервера, Вам пишут что-то типа "Hello, your_name!". На использовании cookies также часто строят функцию оформления заказа в онлайновых магазинах, в частности, в Амазоне, такая своеобразная виртуальная корзина покупателя, как в обычном реальном супермаркете.

У Cookies есть 2 основных параметра: содержание и время жизни, по истечении которого Cookies не передаются серверу. Чтобы с помощью CGI установить Cookies, нужно добавить в HTTP заголовок строку такого вида:

Set-Cookie: key=value; expires=date;

[key=value] - тело;
[date] -время жизни.



Время жизни представляет собой критическую дату, после которой Cookies считается не действительным. Она указывается весьма своеобразным способом:

Set-Cookie: Name=CowBoy; expires=Fri, 31-Dec-02 23:59:59 GMT;

Это значит, что Cookies будут жить только до 31 декабря 2002 года.

Один документ может содержать несколько Cookies. Код ниже формирует HTTP заголовок с установкой Cookies:

print "Content-Type: text/html\n"; print "Status: 200 Ok\n"; print "Set-Cookie: name=Robert; expires=Sat, 26-Aug-03 15:45:30 GMT;\n"; print "Set-Cookie: nick=Pauls; expires=Sat, 26-Aug-03 15:45:30 GMT;\n\n";

Чтобы автоматизировать процесс выставления Cookies, написана процедура set_cookie. Она принимает 3 параметра: время жизни в часах, ключ, значение.

sub set_cookie($$$){ my($year,$date,@day,$ret,$time); $time=time+($_[0]*3600); $year=(localtime($time))[5]; $date=localtime($time); @day=split(/ /,$date); $year =~ s/\d*(\d\d)/$1/; $ret="Set-Cookie: $_[1]=$_[2]; expires="; $ret.="$day[0], $day[2]-$day[1]-$year $day[3] GMT;"; return $ret }

Посмотрите как просто с помощью неё устанавливать Cookies:

print set_cookie(10,"name","Robert"),"\n"; print set_cookie(10,"nick","Pauls"),"\n\n"; sub set_cookie($$$){ my($year,$date,@day,$ret,$time); $time=time+($_[0]*3600); $year=(localtime($time))[5]; $date=localtime($time); $date =~ s/ +/ /g; @day=split(/ /,$date); $year =~ s/\d*(\d\d)/$1/; $ret="Set-Cookie: $_[1]=$_[2]; expires="; $ret.="$day[0], $day[2]-$day[1]-$year $day[3] GMT;"; return $ret }

Чтение ранее записанных значений Cookies производится из переменной окружения $ENV{'HTTP_COOKIE'}. Для удобства получения данных написана процедура get_cookie.

sub get_cookie{ my (@coo_pairs,$pair,$name,$value); @coo_pairs = split(/; /, $ENV{'HTTP_COOKIE'}); foreach $pair (@coo_pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; $COOKIE{$name} = $value;} }

Она создает хеш %COOKIE, в котором данные представлены в виде ключ-значения.

В Cookies можно хранить только символы латинского алфавита, символы нижнего подчеркивания, цифры и знаки % (процент). Обычно такого набора символов хватает для хранения служебной информации.
Чтобы в Cookies можно было хранить все символы таблицы ASCII, доработаем функции передачи следующим образом: будем передавать не сам символ, а его номер в таблице. Для разделения символов будем использовать символ "%". Анологичным образом поступим с функцией приема Cookies, только она будет дешифрировать наши последовательности.

Скрипт ниже создает и считывает значения из Cookies. Все функции модифицированны:

#!/usr/bin/perl print "Content-Type: text/html\n"; print &set_cookie(1,"name","Robert"),"\n"; print &set_cookie(1,"nick","Pauls"),"\n\n"; my ($COOKIE); sub set_cookie($$$){ my($year,$date,@day,$ret,$time,$word); $time=time+($_[0]*3600); $year=(localtime($time))[5]; $date=localtime($time); $date =~ s/ +/ /g; @day=split(/ /,$date); $year =~ s/\d*(\d\d)/$1/; $word=$_[2]; $word =~ s/(.)/"%".ord($1)/eg; $ret="Set-Cookie: $_[1]=$word; expires="; $ret.="$day[0], $day[2]-$day[1]-$year $day[3] GMT;"; return $ret } sub get_cookie{ my (@coo_pairs,$pair,$name,$value); @coo_pairs = split(/; /, $ENV{'HTTP_COOKIE'}); foreach $pair (@coo_pairs) { ($name, $value) = split(/=/, $pair); $value =~ s/%(\d+)/chr($1)/eg; $COOKIE{$name} = $value;} } get_cookie; print $COOKIE{'name'},"
"; print $COOKIE{'nick'};

Содержание раздела