1 PACKAGE BODY owa_cache
2 AS
3
4 --
5 -- Private types and global variables
6 --
7 v_nstatusidx NUMBER := 1; -- the htbuf line index for status header
8 v_netagidx NUMBER := 2; -- the htbuf line index for etag header
9 v_nexpiresidx NUMBER := 2; -- the htbuf line index for expires header
10 v_nlevelidx NUMBER := 3; -- the htbuf line index for level header
11 v_nsurridx NUMBER := 4; -- the htbuf line index for surr-con header
12 v_nendlineidx NUMBER := 5; -- the htbuf line index for end line
13
14 --
15 -- Constants
16 --
17 NL_CHAR constant varchar2(10) := owa_cx.nl_char;
18 expires_header constant VARCHAR2(18) := 'X-ORACLE-EXPIRES: ';
19 etag_header constant VARCHAR2(6) := 'ETag: ';
20 level_header constant VARCHAR2(15) := 'Cache-Control: ';
21 ignore_header constant VARCHAR2(23) := 'X-ORACLE-IGNORE: IGNORE';
22 read_header constant VARCHAR2(20) := 'X-ORACLE-CACHE: READ';
23 write_header constant VARCHAR2(21) := 'X-ORACLE-CACHE: WRITE';
24 surrcon_header constant VARCHAR2(19) := 'Surrogate-Control: ';
25
26 stored_etag VARCHAR2(100) := 'MaGiC_KeY_728374';
27 stored_level VARCHAR2(100) := 'MaGiC_KeY_728374';
28
29 -- Bug 6336258, each element size in htbuf array is 256 bytes
30 -- For Surrogate-Control header, the break-up is as follows
31 -- (19[for header] + 236[max len for the value] + 1[NL_CHAR]) = 256
32 max_surrcon_len constant NUMBER := 236;
33 max_cache_len constant NUMBER := 55;
34 --
35 -- PROCEDURE:
36 -- init
37 -- DESCRIPTION:
38 -- Reserve header spaces
39 -- PARAMS:
40 -- p_htbuf IN/OUT: the buffer to reserve the headers in
41 -- p_rows_in IN/OUT: the current row number in that buffer
42 -- NOTE:
43 -- Should only be called before any data is written to the htbuf
44 --
45 PROCEDURE init(p_htbuf IN OUT NOCOPY htp.htbuf_arr, p_rows_in IN OUT number)
46 IS
47 BEGIN
48 -- Reserve four header spaces
49 p_htbuf(v_nstatusidx) := ignore_header || NL_CHAR;
50 p_htbuf(v_netagidx) := ignore_header || NL_CHAR;
51 p_htbuf(v_nlevelidx) := ignore_header || NL_CHAR;
52 p_htbuf(v_nsurridx) := ignore_header || NL_CHAR;
53 p_htbuf(v_nendlineidx) := NL_CHAR;
54 p_rows_in := 4;
55 END init;
56
57 --
58 -- PROCEDURE:
59 -- disable
60 -- DESCRIPTION:
61 -- Disables the cache
62 --
63 PROCEDURE disable
64 IS
65 BEGIN
66 htp.print_header(ignore_header, v_nstatusidx);
67 htp.print_header(ignore_header, v_netagidx);
68 htp.print_header(ignore_header, v_nlevelidx);
69 htp.print_header(ignore_header, v_nsurridx);
70 END disable;
71
72
73 --
74 -- PROCEDURE:
75 -- set_expires
76 -- DESCRIPTION:
77 -- Sets up the cache headers
78 -- PARAMS:
79 -- p_expires IN: number of minutes this cached item is fresh
80 -- p_level IN: the caching level for it (USER or SYSTEM for now)
81 -- EXCEPTIONS:
82 -- VALUE_ERROR : If p_expires is negative or zero, or p_level is not
83 -- 'USER' or 'SYSTEM', this exception is thrown
84 -- If p_expires is > 525600 (1 year), this exception is thrown
85 --
86 PROCEDURE set_expires(p_expires IN number, p_level IN varchar2)
87 IS
88 BEGIN
89 -- Check for negative numbers or zero
90 IF (p_expires <= 0) THEN
91 raise VALUE_ERROR;
92 END IF;
93
94 -- Check for > 525600
95 IF (p_expires > 525600) THEN
96 raise VALUE_ERROR;
97 END IF;
98
99 -- Check for invalid levels
100 IF (p_level IS NULL) THEN
101 raise VALUE_ERROR;
102 END IF;
103
104 IF (p_level <> 'SYSTEM' AND p_level <> 'USER') THEN
105 raise VALUE_ERROR;
106 END IF;
107
108 htp.print_header(write_header, v_nstatusidx);
109 htp.print_header(expires_header || p_expires, v_nexpiresidx);
110 htp.print_header(level_header || p_level, v_nlevelidx);
111 END set_expires;
112
113
114 --
115 -- PROCEDURE:
116 -- set_cache
117 -- DESCRIPTION:
118 -- Sets up the cache headers
119 -- PARAMS:
120 -- p_etag IN: the ETag associated with this content
121 -- p_level IN: the caching level for it (USER or SYSTEM for now)
122 -- EXCEPTIONS:
123 -- VALUE_ERROR : If p_etag is greater than max_cache_len in length or
124 -- p_level is not 'USER' or 'SYSTEM', this exception is thrown
125 --
126 PROCEDURE set_cache(p_etag IN varchar2, p_level IN varchar2)
127 IS
128 BEGIN
129 -- Check for the etag length
130 IF (p_etag IS NULL OR length(p_etag) > max_cache_len) THEN
131 raise VALUE_ERROR;
132 END IF;
133
134 -- Check for invalid levels
135 IF (p_level IS NULL) THEN
136 raise VALUE_ERROR;
137 END IF;
138
139 IF (p_level <> 'SYSTEM' AND p_level <> 'USER') THEN
140 raise VALUE_ERROR;
141 END IF;
142
143 htp.print_header(write_header, v_nstatusidx);
144 htp.print_header(etag_header || p_etag, v_netagidx);
145 htp.print_header(level_header || p_level, v_nlevelidx);
146 END set_cache;
147
148
149 --
150 -- PROCEDURE:
151 -- set_not_modified
152 -- DESCRIPTION:
153 -- Sets up the headers for a not modified cache hit
154 -- EXCEPTIONS:
155 -- VALUE_ERROR : If the ETag or Cache-Control wasn't passed in,
156 -- this exception is thrown
157 --
158 PROCEDURE set_not_modified
159 IS
160 BEGIN
161 IF (get_etag IS NULL OR get_level IS NULL) THEN
162 raise VALUE_ERROR;
163 END IF;
164
165 htp.print_header(read_header, v_nstatusidx);
166 htp.print_header(ignore_header, v_netagidx);
167 htp.print_header(ignore_header, v_nlevelidx);
168 END set_not_modified;
169
170
171 --
172 -- PROCEDURE:
173 -- set_surrogate_control
174 -- DESCRIPTION:
175 -- Sets up the headers for a surrogate-control header for web cache
176 -- PARAMS:
177 -- p_value IN: value to be passed as the Surrogate-Control header
178 -- EXCEPTIONS:
179 -- VALUE_ERROR : If p_value is greater than max_surrcon_len in length
180 --
181 PROCEDURE set_surrogate_control(p_value IN varchar2)
182 IS
183 BEGIN
184 -- Check for the value length
185 IF (p_value IS NULL OR length(p_value) > max_surrcon_len) THEN
186 raise VALUE_ERROR;
187 END IF;
188
189 htp.print_header(surrcon_header || p_value, v_nsurridx);
190 END set_surrogate_control;
191
192 --
193 -- FUNCTION:
194 -- get_level
195 -- DESCRIPTION:
196 -- Returns the caching level
197 -- PARAMS:
198 -- none
199 -- RETURN:
200 -- The caching level string (USER or SYSTEM for now)
201 --
202 FUNCTION get_level
203 RETURN VARCHAR2
204 IS
205 BEGIN
206 IF (stored_level = 'MaGiC_KeY_728374') THEN
207 stored_level := owa_util.get_cgi_env('HTTP_CACHE_CONTROL');
208 END IF;
209 RETURN stored_level;
210 END get_level;
211
212 --
213 -- FUNCTION:
214 -- get_etag
215 -- DESCRIPTION:
216 -- Returns the caching etag
217 -- PARAMS:
218 -- none
219 -- RETURN:
220 -- The caching etag string
221 --
222 FUNCTION get_etag
223 RETURN VARCHAR2
224 IS
225 BEGIN
226 IF (stored_etag = 'MaGiC_KeY_728374') THEN
227 stored_etag := owa_util.get_cgi_env('HTTP_IF_MATCH');
228 END IF;
229 RETURN stored_etag;
230 END get_etag;
231 END owa_cache;