From: "Pascal Obry" <p.obry@der.edf.fr>
Subject: Re: cookies
Date: 1998/09/17
Date: 1998-09-17T00:00:00+00:00 [thread overview]
Message-ID: <6tqfe6$kk1$1@cf01.edf.fr> (raw)
In-Reply-To: 6tpv6c$o1l$1@emu.cs.rmit.edu.au
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 12086 bytes --]
Lisa Winkworth a �crit dans le message <6tpv6c$o1l$1@emu.cs.rmit.edu.au>...
>Hi, does anyone have any idea how to accept/generally do stuff with cookies
>in ada95??
>Any help would be much appreciated :)
>Thanks in advance,
>Lisa
>
Lisa,
I have done a child package of cgi.ads (from David A. Wheeler) to handle
cookies.
The packages spec/body are small so I have included them in this message.
Pascal.
---------------------------------- CUT
HERE -----------------------------------------------
-- File Name : cgi-cookies.ads
--
-- Created by : Pascal Obry
-- on : Mon Mar 10 16:05:01 1997
with Ada.Strings.Unbounded;
package CGI.Cookies is
use Ada.Strings.Unbounded;
-- Get cookie number
function Count return Natural;
-- Get cookies value
function Value
(Key : in Unbounded_String;
Required : in Boolean := False)
return Unbounded_String;
function Value
(Key : in String;
Required : in Boolean := False)
return Unbounded_String;
function Value
(Key : in String;
Required : in Boolean := False)
return String;
function Value
(Key : in Unbounded_String;
Required : in Boolean := False)
return String;
-- Was a given key provided?
function Key_Exists (Key : in String) return Boolean;
function Key_Exists (Key : in Unbounded_String) return Boolean;
-- Set cookies value
procedure Set (Key : in String;
Value : in String;
Expires : in String := "";
Path : in String := "/";
Domain : in String := "";
Secure : in Boolean := False);
-- Send cookies to client with HTML header.
procedure Put_CGI_Header_With_Cookies
(Header : in String := "Content-type: text/html");
end CGI.Cookies;
-- File Name : cgi-cookies.adb
--
-- Created by : Pascal Obry
-- on : Mon Mar 10 16:05:01 1997
with Ada.Text_IO;
with Ada.Strings.Maps;
with Ada.Characters.Handling;
with Table_Of_Static_Keys_And_Static_Values_G;
package body CGI.Cookies is
use Ada;
use Ada.Strings.Maps;
-- to set cookie
type Key_Values_Record is
record
Value : Unbounded_String;
Expires : Unbounded_String;
Path : Unbounded_String;
Domain : Unbounded_String;
Secure : Boolean := False;
end record;
package Cookie_Table is
new Table_Of_Static_Keys_And_Static_Values_G (Unbounded_String,
"<",
"=",
Key_Values_Record);
-- to hold cookie value sent be the client
type Key_Value_Pair is
record
Key : Unbounded_String;
Value : Unbounded_String;
end record;
type Key_Value_Sequence is array (Positive range <>) of Key_Value_Pair;
type Access_Key_Value_Sequence is access Key_Value_Sequence;
-- The following are data internal to this package.
Cookie_Data : Access_Key_Value_Sequence;
Set_Cookie_Data : Cookie_Table.Table_Type;
Ampersands : constant Character_Set := To_Set ('&');
Equals : constant Character_Set := To_Set ('=');
Plus_To_Space : constant Character_Mapping := To_Mapping ("+", " ");
------------------------------
-- Get cookie number
function Count return Natural is
begin
if Cookie_Data = null then
return 0;
else
return Cookie_Data'Length;
end if;
end Count;
------------------------------
-- Get cookies value
function Value
(Key : in Unbounded_String;
Required : in Boolean := False)
return Unbounded_String is
begin
for I in 1 .. Count loop
if Cookie_Data (I).Key = Key then
return Cookie_Data (I).Value;
end if;
end loop;
-- Didn't find the Key.
if Required then
raise Constraint_Error;
else
return Null_Unbounded_String;
end if;
end Value;
------------------------------
function Value
(Key : in String;
Required : in Boolean := False)
return Unbounded_String
is
begin
return Value (To_Unbounded_String (Key), Required);
end Value;
------------------------------
function Value
(Key : in String;
Required : in Boolean := False)
return String
is
begin
return To_String (Value (To_Unbounded_String (Key), Required));
end Value;
------------------------------
function Value
(Key : in Unbounded_String;
Required : in Boolean := False)
return String
is
begin
return To_String (Value (Key, Required));
end Value;
------------------------------
-- Was a given key provided?
function Key_Exists (Key : in Unbounded_String)
return Boolean
is
begin
for I in 1 .. Count loop
if Cookie_Data (I).Key = Key then
return True;
end if;
end loop;
return False;
end Key_Exists;
------------------------------
function Key_Exists (Key : in String)
return Boolean
is
begin
return Key_Exists (To_Unbounded_String (Key));
end Key_Exists;
------------------------------
-- Set cookie value
procedure Set (Key : in String;
Value : in String;
Expires : in String := "";
Path : in String := "/";
Domain : in String := "";
Secure : in Boolean := False)
is
Cookie_Record : Key_Values_Record;
begin -- Set_Cookies
Cookie_Record := (To_Unbounded_String (Value),
To_Unbounded_String (Expires),
To_Unbounded_String (Path),
To_Unbounded_String (Domain),
Secure);
Cookie_Table.Insert_Or_Replace_Value (Set_Cookie_Data,
To_Unbounded_String (Key),
Cookie_Record);
end Set;
------------------------------
procedure Put_CGI_Header_With_Cookies
(Header : in String := "Content-type: text/html")
is
procedure Put_Cookie (Key : in Unbounded_String;
Datas : in Key_Values_Record;
N : in Positive;
Continue : in out Boolean) is
begin
Text_IO.Put ("Set-Cookie: ");
Text_IO.Put (To_String (Key) & '=' & To_String (Datas.Value));
if Datas.Expires /= Null_Unbounded_String then
Text_IO.Put ("; expires=" & To_String (Datas.Expires));
end if;
if Datas.Path /= Null_Unbounded_String then
Text_IO.Put ("; path=" & To_String (Datas.Path));
end if;
if Datas.Domain /= Null_Unbounded_String then
Text_IO.Put ("; domain=" & To_String (Datas.Domain));
end if;
if Datas.Secure then
Text_IO.Put ("; secure");
end if;
Text_IO.New_Line;
Continue := True;
end Put_Cookie;
procedure For_Every_Cookies is
new Cookie_Table.Traverse_ASC_G (Put_Cookie);
begin
-- CGI Header
Text_IO.Put_Line (Header);
-- Cookies
For_Every_Cookies (Set_Cookie_Data);
Text_IO.New_Line;
end Put_CGI_Header_With_Cookies;
------------------------------
-- Initialization routines, including some private procedures only
-- used during initialization.
function Field_End
(Data : Unbounded_String;
Field_Separator : Character;
Starting_At : Positive := 1)
return Natural
is
-- Return the end-of-field position in Data after "Starting_Index",
-- assuming that fields are separated by the Field_Separator.
-- If there's no Field_Separator, return the end of the Data.
begin
for I in Starting_At .. Length (Data) loop
if Element (Data, I) = Field_Separator then
return I - 1;
end if;
end loop;
return Length (Data);
end Field_End;
------------------------------
function Hex_Value (H : in String) return Natural is
-- Given hex string, return its Value as a Natural.
Value : Natural := 0;
begin
for P in 1.. H'Length loop
Value := Value * 16;
if H(P) in '0' .. '9' then
Value := Value + Character'Pos(H(P)) - Character'Pos('0');
elsif H(P) in 'A' .. 'F' then
Value := Value + Character'Pos(H(P)) - Character'Pos('A') + 10;
elsif H(P) in 'a' .. 'f' then
Value := Value + Character'Pos(H(P)) - Character'Pos('a') + 10;
else
raise Constraint_Error;
end if;
end loop;
return Value;
end Hex_Value;
------------------------------
procedure Decode (Data : in out Unbounded_String)
is
use Characters.Handling;
I : Positive := 1;
-- In the given string, convert pattern %HH into alphanumeric
characters,
-- where HH is a hex number. Since this encoding only permits values
-- from %00 to %FF, there's no need to handle 16-bit characters.
begin
while I <= Length(Data) - 2 loop
if Element (Data, I) = '%' and
Is_Hexadecimal_Digit (Element (Data, I+1)) and
Is_Hexadecimal_Digit (Element (Data, I+2)) then
Replace_Element
(Data, I,
Character'Val (Hex_Value (Slice (Data, I+1, I+2))));
Delete (Data, I+1, I+2);
end if;
I := I + 1;
end loop;
end Decode;
------------------------------
procedure Set_CGI_Position
(Key_Number : in Positive;
Datum : in Unbounded_String)
is
Last : Natural := Field_End(Datum, '=');
-- Given a Key number and a datum of the form key=value
-- assign the CGI_Data(Key_Number) the values of key and value.
begin
Cookie_Data (Key_Number).Key
:= To_Unbounded_String (Slice (Datum, 1, Last));
Cookie_Data (Key_Number).Value
:= To_Unbounded_String (Slice (Datum, Last+2, Length (Datum)));
Decode (Cookie_Data (Key_Number).Key);
Decode (Cookie_Data (Key_Number).Value);
end Set_CGI_Position;
------------------------------
procedure Set_CGI_Data (Raw_Data : in Unbounded_String) is
-- Set CGI_Data using Raw_Data.
Key_Number : Positive := 1;
Character_Position : Positive := 1;
Last : Natural;
begin
while Character_Position <= Length (Raw_Data) loop
Last := Field_End (Raw_Data, ';', Character_Position);
Set_CGI_Position
(Key_Number,
To_Unbounded_String (Slice (Raw_Data, Character_Position,
Last)));
Character_Position := Last + 3; -- Skip over field separator. "; "
Key_Number := Key_Number + 1;
end loop;
end Set_CGI_Data;
------------------------------
procedure Initialize is
Raw_Data : Unbounded_String;
begin
Raw_Data := To_Unbounded_String (Get_Environment("HTTP_COOKIE"));
Translate (Raw_Data, Mapping => Plus_To_Space);
if Length (Raw_Data) > 0 then
Cookie_Data :=
new Key_Value_Sequence (1 .. Count (Raw_Data, ";") + 1);
Set_CGI_Data (Raw_Data);
end if;
end Initialize;
begin
Initialize;
end CGI.Cookies;
---------------------------------- CUT
HERE -----------------------------------------------
next prev parent reply other threads:[~1998-09-17 0:00 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
1998-09-17 0:00 cookies Lisa Winkworth
1998-09-17 0:00 ` Pascal Obry [this message]
1998-09-17 0:00 ` cookies Dale Stanbrough
1998-09-17 0:00 ` cookies David C. Hoos, Sr
1998-09-23 0:00 ` cookies Lisa Winkworth
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox