-
Notifications
You must be signed in to change notification settings - Fork 0
/
pcookie.html
291 lines (204 loc) · 7.84 KB
/
pcookie.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta name="keywords" content="Yaws"/>
<title>Yaws</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" type="text/css" href="stil.css"/>
<link rel="shortcut icon" href="/icons/yaws_y.gif" type="image/x-icon"/>
</head>
<body>
<div class="logo">
<img src="icons/yaws_head.gif" width="600" alt="YAWS"/>
</div>
<div id="sidebar">
<h4> Yaws </h4>
<div class=""> <a href="index.html" id="index" >Top Page</a> </div>
<div class=""> <a href="configuration.html" id="configuration">Build Config and Run</a></div>
<div class=""> <a href="dynamic.html" id="dynamic" >Dynamic Content</a> </div>
<div class=""> <a href="https://github.com/erlyaws/yaws/releases/" id="download">Download </a> </div>
<div class=""> <a href="contact.html" id="contact">Contact </a> </div>
<div class=""> <a href="doc.html" id="doc">Documentation</a> </div>
<div class=""> <a href="articles.html" id="resources">Articles</a> </div>
<h4> Examples </h4>
<div class=""> <a href="/json_intro.html">AJAX/JSON RPC</a></div>
<div class=""> <a href="/appmods.html">Appmods</a> </div>
<div class=""> <a href="/arg.html">Arg</a> </div>
<div class=""> <a href="/privbind.html">Binding to Privileged Ports</a></div>
<div class=""> <a href="/bindings.html">Bindings</a> </div>
<div class=""> <a href="/cgi.html">CGI</a></div>
<div class=""> <a href="/session.html">Cookie Sessions</a> </div>
<div class=""> <a href="/cookies.html">Cookies</a> </div>
<div class=""> <a href="/dynamic.html">Dynamic Content</a> </div>
<div class=""> <a href="/embed.html">Embedding Yaws</a></div>
<div class=""> <a href="/upload0.html">File Upload</a> </div>
<div class=""> <a href="/form.html">Forms</a> </div>
<div class=""> <a href="/haxe_intro.html">haXe Remoting</a></div>
<div class="choosen"> <a href="/pcookie.html">Persistent Cookies</a> </div>
<div class=""> <a href="/query.html">Query Part of URL</a></div>
<div class=""> <a href="/rebar_release.html">Rebar Releases</a></div>
<div class=""> <a href="/redirect.html">Redirect</a> </div>
<div class=""> <a href="/server_sent_events.html">Server-Sent Events</a> </div>
<div class=""> <a href="/ssi.html">Server Side Includes</a> </div>
<div class=""> <a href="/simple.html">Simple</a> </div>
<div class=""> <a href="/soap_intro.html">SOAP with Yaws</a></div>
<div class=""> <a href="/stream.html">Streaming Data</a> </div>
<div class=""> <a href="/websockets.html">Web Sockets</a> </div>
<a href="/shoppingcart/index.html">Tiny Shopping Cart</a>
<div class=""> <a href="/yapp_intro.html">Yaws Applications (yapps)</a></div>
<div class=""> <a href="/logger_mod.html">Write Your Own Logger</a></div>
<h4> Misc </h4>
<div class=""> <a href="/internals.html">Internals</a> </div>
</div>
<div id="entry">
<h1>Persistent Cookies</h1>
<p>
We saw in the first <a href="cookies.html">cookie</a> example, how we
assigned a special erlang process to handle each session.
The cookie has an expiry date, and the correct thing would be to let the
handling process live as long as the cookie is valid. This is not a good option.
A better option is to store cookie in a persistant storage. This can be an
ets table or a dets table. If we choose an ets table, the cookies will disappear
when the yaws server is restarted, whereas if we choose a dets table,
the cookies will survive daemon restarts. What to choose depends on the
type of cookie information we have.
</p>
<p>
The yaws code in
<a href="setpcookie.html">setpcookie.yaws</a> sets the cookie in the browser.
</p>
<p>And the yaws code in <a href="readpcookie.html">readpcookie.yaws</a>
will read the cookie
</p>
<p>
Let's show some code. To set the cookie we we have:
</p>
<br><br>
<div class="box"> <pre>
<erl>
-export([pserv/0]).
ensure_pcookie_server() ->
case whereis(pcookie_server) of
undefined ->
proc_lib:start(?MODULE, pserv,[]);
_ ->
ok
end.
pserv() ->
catch begin
register(pcookie_server, self()),
T = ets:new(pcookies, [set, public,
named_table]),
ets:insert(T, {counter, 0})
end,
proc_lib:init_ack(ok),
pserv_loop().
pserv_loop() ->
receive
X ->
pserv_loop()
end.
setcookie(A) ->
Num = ets:update_counter(pcookies, counter, 1),
Data = {(A#arg.headers)#headers.user_agent,
calendar:local_time(),
inet:peername(A#arg.clisock)},
ets:insert(pcookies, {{cookie, Num}, Data}),
yaws_api:set_cookie("pfoobar",integer_to_list(Num),
[{path,"/"}]).
out(A) ->
ensure_pcookie_server(),
H = A#arg.headers,
C = H#headers.cookie,
case C of
[Cookie|_] ->
case string:tokens(Cookie, [$=]) of
["pfoobar", NumStr] ->
Num = list_to_integer(NumStr),
%% cookie allready set
case ets:lookup(pcookies, {c, Num}) of
[{cookie, Data}] ->
ok; %% cookie already set
[] ->
setcookie(A)
end;
_ ->
setcookie(A)
end;
_ ->
setcookie(A)
end.
</erl>
<erl>
out(A) -> {ssi, "TAB.inc", [],[]}.
</erl>
<div id="entry">
<h2> Set persistent cookie </h2>
<p>This is the page that set a persistent cookie in
the browser.
<a href="readpcookie.yaws">readpcookie.yaws</a> will
read the cookie and report persistent information.
</div>
<erl>
out(A) -> {ssi, "END2",[],[]}.
</erl>
</pre></div>
<br>
<p>
And to read the cookie, we have the following code:
</p>
<br><br>
<div class="box"> <pre>
<html>
<h2> Read persistent cookie </h2>
<erl>
to_integer(S) ->
list_to_integer(string:strip(S, both)).
out(A) ->
H=A#arg.headers,
C = H#headers.cookie,
L=case yaws_api:find_cookie_val("pfoobar", C) of
[] ->
f("<p> No cookie set from the browser, need to "
"visit <a href=\"setpcookie.yaws\">setpcookie.yaws</a> "
"to set the cookie first </p>~n", []);
NumStr ->
Num = to_integer(NumStr),
case ets:lookup(pcookies, {cookie,Num}) of
[{{cookie, Num}, Data}] ->
f("<p> Yes, I read your cookie:it is ~p~n "
"Your persistent info is ~n"
"<pre>~n~p~n</pre> </p>~n", [NumStr, Data]);
[] ->
f("<p> You had a cookie,but the data is gone </p>",[])
end
end,
{html, L}.
</erl>
<p>
The code to read the cookie, is simple, we get the cookie passed to the yaws
code in the #arg structure which is the argument supplied to the out/1 function.
The code is:</p>
<erl>
out(A) ->
{ok, B} = file:read_file(A#arg.docroot ++ "/readpcookie.yaws"),
{ehtml,
{'div', [{class, "box"}],
{pre,[], B}}}.
</erl>
</html>
</pre></div>
<br>
</div>
<div class="logo">
<img src="/icons/yaws_pb.gif" alt="pbyaws" />
</div>
<p>
<a href="https://validator.w3.org/check?uri=referer"><img
src="https://www.w3.org/Icons/valid-xhtml10"
alt="Valid XHTML 1.0!" height="31" width="88" /></a>
</p>
</body>
</html>