1 package body OWA_COOKIE is
2
3 cookie_names vc_arr;
4 cookie_vals vc_arr;
5 cookie_num_vals integer;
6
7 cookies_parsed boolean;
8
9 /* Constant is set here instead of owachars to avoid invalid objects */
10 SC_CHAR constant varchar2(10) := chr(59); /* SemiColon */
11
12 function validate_cookie_val(
13 param in varchar2
14 ) return varchar2 is
15 valid_param varchar2(32767);
16 begin
17 if (param is NULL)
18 then
19 return param;
20 end if;
21
22 valid_param := param;
23 if instr(valid_param,(SC_CHAR)) > 0
24 then
25 valid_param := owa_util.validate_arg(
26 substr(valid_param,1,instr(valid_param,(SC_CHAR)) - 1));
27 end if;
28
29 return valid_param;
30 end;
31
32 procedure init is
33 begin
34 cookies_parsed := FALSE;
35 end init;
36
37 function IFNOTNULL(val1 in varchar2,
38 val2 in varchar2) return varchar2 is
39 begin
40 if (val1 is not null)
41 then
42 return val2;
43 else
44 return NULL;
45 end if;
46 end;
47
48 procedure http_cookie2array(names out vc_arr,
49 vals out vc_arr,
50 num_vals out integer) is
51 http_cookie varchar2(32767);
52
53 start_loc integer;
54 end_loc integer;
55 equal_sign integer;
56
57 val_counter integer;
58 begin
59 http_cookie := owa_util.get_cgi_env('HTTP_COOKIE');
60
61 val_counter := 0;
62
63 /* If the last character is a ';', trim it out */
64 if (substr(http_cookie, -1) = ';')
65 then
66 http_cookie := substr(http_cookie, 1, length(http_cookie)-1);
67 end if;
68
69 if (http_cookie is not NULL)
70 then
71 start_loc := 1;
72 end_loc := instr(http_cookie, ';', start_loc);
73 while (end_loc != 0)
74 loop
75 val_counter := val_counter+1;
76 equal_sign := instr(http_cookie, '=', start_loc);
77
78 -- If the equal sign is beyond this cookie, set the value to null
79 if (equal_sign = 0 or equal_sign > end_loc)
80 then
81 names(val_counter) := ltrim(substr(http_cookie, start_loc,
82 end_loc - start_loc));
83 vals(val_counter) := null;
84 else
85 names(val_counter) := ltrim(substr(http_cookie, start_loc,
86 equal_sign-start_loc));
87 vals(val_counter) := substr(http_cookie, equal_sign+1,
88 end_loc - equal_sign - 1);
89 end if;
90
91 start_loc := end_loc + 1;
92 end_loc := instr(http_cookie, ';', start_loc);
93 end loop;
94
95 val_counter := val_counter + 1;
96 equal_sign := instr(http_cookie, '=', start_loc);
97
98 -- If there is no equal sign in last cookie, set the value to null
99 if (equal_sign = 0)
100 then
101 names(val_counter) := ltrim(substr(http_cookie, start_loc));
102 vals(val_counter) := null;
103 else
104 names(val_counter) := ltrim(substr(http_cookie, start_loc,
105 equal_sign-start_loc));
106 vals(val_counter) := substr(http_cookie, equal_sign+1);
107 end if;
108
109 end if;
110
111 num_vals := val_counter;
112 end;
113
114 procedure send(name in varchar2,
115 value in varchar2,
116 expires in date DEFAULT NULL,
117 path in varchar2 DEFAULT NULL,
118 domain in varchar2 DEFAULT NULL,
119 secure in varchar2 DEFAULT NULL,
120 httponly in varchar2 DEFAULT NULL) is
121 expires_gmt date;
122 l_name varchar2(32767);
123 l_value varchar2(32767);
124 l_path varchar2(32767);
125 l_domain varchar2(32767);
126 l_secure varchar2(32767);
127 l_httponly varchar2(32767);
128 begin
129 -- Validate parameters
130 l_name := owa_util.validate_arg(name);
131 l_value := validate_cookie_val(value);
132 l_path := owa_util.validate_arg(path);
133 l_domain := owa_util.validate_arg(domain);
134 l_secure := owa_util.validate_arg(secure);
135 l_httponly := owa_util.validate_arg(httponly);
136
137 if (OWA_CUSTOM.DBMS_SERVER_GMTDIFF is not NULL)
138 then
139 expires_gmt := expires-(OWA_CUSTOM.DBMS_SERVER_GMTDIFF/24);
140 else
141 expires_gmt := new_time(expires,OWA_CUSTOM.DBMS_SERVER_TIMEZONE,'GMT');
142 end if;
143
144 -- When setting the cookie expiration header
145 -- we need to set the nls date language to AMERICAN
146 -- since the cookie line needs to be in English.
147 -- If the NLS_LANGUAGE of the database is other than
148 -- English, the expires tag is not understood by the browser.
149 htp.print('Set-Cookie: '||l_name||'='||l_value||';'||
150 IFNOTNULL(expires_gmt, ' expires='||
151 rtrim(to_char(expires_gmt,'Dy',
152 'NLS_DATE_LANGUAGE=American NLS_CALENDAR=Gregorian'))||
153 to_char
154 (
155 expires_gmt,
156 ', DD-Mon-YYYY HH24:MI:SS',
157 'NLS_DATE_LANGUAGE=American NLS_CALENDAR=Gregorian'
158 )||' GMT;')||
159 IFNOTNULL(l_path, ' path='||l_path||';')||
160 IFNOTNULL(l_domain, ' domain='||l_domain||';')||
161 IFNOTNULL(l_secure, ' secure;')||
162 IFNOTNULL(l_httponly, ' HttpOnly'));
163 end;
164
165 function make_cookie(name in varchar2 DEFAULT NULL) return cookie is
166 choc_chip cookie;
167 begin
168 choc_chip.num_vals := 0;
169 choc_chip.name := name;
170
171 return choc_chip;
172 end;
173
174 function get(name in varchar2) return cookie is
175 choc_chip cookie;
176 begin
177 if (NOT cookies_parsed)
178 then
179 http_cookie2array(cookie_names, cookie_vals, cookie_num_vals);
180 cookies_parsed := TRUE;
181 end if;
182
183 choc_chip := make_cookie(name);
184
185 /* This is not the most efficient thing to do. */
186 /* should probably have cookie2array sort */
187 /* then we could do binary search here. */
188 for i in 1..cookie_num_vals
189 loop
190 if (cookie_names(i) = name)
191 then
192 choc_chip.num_vals := choc_chip.num_vals + 1;
193 choc_chip.vals(choc_chip.num_vals) := cookie_vals(i);
194 end if;
195 end loop;
196
197 return choc_chip;
198 end;
199
200 procedure remove(name in varchar2,
201 val in varchar2,
202 path in varchar2 DEFAULT NULL) is
203 begin
204 send(name, val, to_date('01-01-1990','DD-MM-YYYY'));
205 end;
206
207 procedure get_all(names out vc_arr,
208 vals out vc_arr,
209 num_vals out integer) is
210 begin
211 if (NOT cookies_parsed)
212 then
213 http_cookie2array(cookie_names, cookie_vals, cookie_num_vals);
214 cookies_parsed := TRUE;
215 end if;
216 names := cookie_names;
217 vals := cookie_vals;
218 num_vals := cookie_num_vals;
219 end;
220
221 begin
222 cookies_parsed := FALSE;
223 end;