1d4afb5ceSopenharmony_ci/*
2d4afb5ceSopenharmony_ci * lws-api-test-lws_cache
3d4afb5ceSopenharmony_ci *
4d4afb5ceSopenharmony_ci * Written in 2010-2021 by Andy Green <andy@warmcat.com>
5d4afb5ceSopenharmony_ci *
6d4afb5ceSopenharmony_ci * This file is made available under the Creative Commons CC0 1.0
7d4afb5ceSopenharmony_ci * Universal Public Domain Dedication.
8d4afb5ceSopenharmony_ci */
9d4afb5ceSopenharmony_ci
10d4afb5ceSopenharmony_ci#include <libwebsockets.h>
11d4afb5ceSopenharmony_ci
12d4afb5ceSopenharmony_cistatic struct lws_context *cx;
13d4afb5ceSopenharmony_cistatic int tests, fail;
14d4afb5ceSopenharmony_ci
15d4afb5ceSopenharmony_cistatic int
16d4afb5ceSopenharmony_citest_just_l1(void)
17d4afb5ceSopenharmony_ci{
18d4afb5ceSopenharmony_ci	struct lws_cache_creation_info ci;
19d4afb5ceSopenharmony_ci	struct lws_cache_ttl_lru *l1;
20d4afb5ceSopenharmony_ci	int ret = 1;
21d4afb5ceSopenharmony_ci	size_t size;
22d4afb5ceSopenharmony_ci	char *po;
23d4afb5ceSopenharmony_ci
24d4afb5ceSopenharmony_ci	lwsl_user("%s\n", __func__);
25d4afb5ceSopenharmony_ci
26d4afb5ceSopenharmony_ci	tests++;
27d4afb5ceSopenharmony_ci
28d4afb5ceSopenharmony_ci	/* just create a heap cache "L1" */
29d4afb5ceSopenharmony_ci
30d4afb5ceSopenharmony_ci	memset(&ci, 0, sizeof(ci));
31d4afb5ceSopenharmony_ci	ci.cx = cx;
32d4afb5ceSopenharmony_ci	ci.ops = &lws_cache_ops_heap;
33d4afb5ceSopenharmony_ci	ci.name = "L1";
34d4afb5ceSopenharmony_ci
35d4afb5ceSopenharmony_ci	l1 = lws_cache_create(&ci);
36d4afb5ceSopenharmony_ci	if (!l1)
37d4afb5ceSopenharmony_ci		goto cdone;
38d4afb5ceSopenharmony_ci
39d4afb5ceSopenharmony_ci	/* add two items, a has 1s expiry and b has 2s */
40d4afb5ceSopenharmony_ci
41d4afb5ceSopenharmony_ci	if (lws_cache_write_through(l1, "a", (const uint8_t *)"is_a", 5,
42d4afb5ceSopenharmony_ci				    lws_now_usecs() + LWS_US_PER_SEC, NULL))
43d4afb5ceSopenharmony_ci		goto cdone;
44d4afb5ceSopenharmony_ci
45d4afb5ceSopenharmony_ci	if (lws_cache_write_through(l1, "b", (const uint8_t *)"is_b", 5,
46d4afb5ceSopenharmony_ci				    lws_now_usecs() + LWS_US_PER_SEC * 2, NULL))
47d4afb5ceSopenharmony_ci		goto cdone;
48d4afb5ceSopenharmony_ci
49d4afb5ceSopenharmony_ci	/* check they exist as intended */
50d4afb5ceSopenharmony_ci
51d4afb5ceSopenharmony_ci	if (lws_cache_item_get(l1, "a", (const void **)&po, &size) ||
52d4afb5ceSopenharmony_ci	    size != 5 || strcmp(po, "is_a"))
53d4afb5ceSopenharmony_ci		goto cdone;
54d4afb5ceSopenharmony_ci
55d4afb5ceSopenharmony_ci	if (lws_cache_item_get(l1, "b", (const void **)&po, &size) ||
56d4afb5ceSopenharmony_ci	    size != 5 || strcmp(po, "is_b"))
57d4afb5ceSopenharmony_ci		goto cdone;
58d4afb5ceSopenharmony_ci
59d4afb5ceSopenharmony_ci	/* wait for 1.2s to pass, working the event loop by hand */
60d4afb5ceSopenharmony_ci
61d4afb5ceSopenharmony_ci	lws_cancel_service(cx);
62d4afb5ceSopenharmony_ci	if (lws_service(cx, 0) < 0)
63d4afb5ceSopenharmony_ci		goto cdone;
64d4afb5ceSopenharmony_ci#if defined(WIN32)
65d4afb5ceSopenharmony_ci	Sleep(1200);
66d4afb5ceSopenharmony_ci#else
67d4afb5ceSopenharmony_ci	/* netbsd cares about < 1M */
68d4afb5ceSopenharmony_ci	usleep(999999);
69d4afb5ceSopenharmony_ci	usleep(200001);
70d4afb5ceSopenharmony_ci#endif
71d4afb5ceSopenharmony_ci	lws_cancel_service(cx);
72d4afb5ceSopenharmony_ci	if (lws_service(cx, 0) < 0)
73d4afb5ceSopenharmony_ci		goto cdone;
74d4afb5ceSopenharmony_ci
75d4afb5ceSopenharmony_ci	lws_cancel_service(cx);
76d4afb5ceSopenharmony_ci	if (lws_service(cx, 0) < 0)
77d4afb5ceSopenharmony_ci		goto cdone;
78d4afb5ceSopenharmony_ci
79d4afb5ceSopenharmony_ci	/* a only had 1s lifetime, he should be gone */
80d4afb5ceSopenharmony_ci
81d4afb5ceSopenharmony_ci	if (!lws_cache_item_get(l1, "a", (const void **)&po, &size)) {
82d4afb5ceSopenharmony_ci		lwsl_err("%s: cache: a still exists after expiry\n", __func__);
83d4afb5ceSopenharmony_ci		fail++;
84d4afb5ceSopenharmony_ci		goto cdone;
85d4afb5ceSopenharmony_ci	}
86d4afb5ceSopenharmony_ci
87d4afb5ceSopenharmony_ci	/* that's ok then */
88d4afb5ceSopenharmony_ci
89d4afb5ceSopenharmony_ci	ret = 0;
90d4afb5ceSopenharmony_ci
91d4afb5ceSopenharmony_cicdone:
92d4afb5ceSopenharmony_ci	lws_cache_destroy(&l1);
93d4afb5ceSopenharmony_ci
94d4afb5ceSopenharmony_ci	if (ret)
95d4afb5ceSopenharmony_ci		lwsl_warn("%s: fail\n", __func__);
96d4afb5ceSopenharmony_ci
97d4afb5ceSopenharmony_ci	return ret;
98d4afb5ceSopenharmony_ci}
99d4afb5ceSopenharmony_ci
100d4afb5ceSopenharmony_cistatic int
101d4afb5ceSopenharmony_citest_just_l1_limits(void)
102d4afb5ceSopenharmony_ci{
103d4afb5ceSopenharmony_ci	struct lws_cache_creation_info ci;
104d4afb5ceSopenharmony_ci	struct lws_cache_ttl_lru *l1;
105d4afb5ceSopenharmony_ci	int ret = 1;
106d4afb5ceSopenharmony_ci	size_t size;
107d4afb5ceSopenharmony_ci	char *po;
108d4afb5ceSopenharmony_ci
109d4afb5ceSopenharmony_ci	lwsl_user("%s\n", __func__);
110d4afb5ceSopenharmony_ci	tests++;
111d4afb5ceSopenharmony_ci
112d4afb5ceSopenharmony_ci	/* just create a heap cache "L1" */
113d4afb5ceSopenharmony_ci
114d4afb5ceSopenharmony_ci	memset(&ci, 0, sizeof(ci));
115d4afb5ceSopenharmony_ci	ci.cx = cx;
116d4afb5ceSopenharmony_ci	ci.ops = &lws_cache_ops_heap;
117d4afb5ceSopenharmony_ci	ci.name = "L1_lim";
118d4afb5ceSopenharmony_ci	ci.max_items = 1; /* ie, adding a second item destroys the first */
119d4afb5ceSopenharmony_ci
120d4afb5ceSopenharmony_ci	l1 = lws_cache_create(&ci);
121d4afb5ceSopenharmony_ci	if (!l1)
122d4afb5ceSopenharmony_ci		goto cdone;
123d4afb5ceSopenharmony_ci
124d4afb5ceSopenharmony_ci	/* add two items, a has 1s expiry and b has 2s */
125d4afb5ceSopenharmony_ci
126d4afb5ceSopenharmony_ci	if (lws_cache_write_through(l1, "a", (const uint8_t *)"is_a", 5,
127d4afb5ceSopenharmony_ci				    lws_now_usecs() + LWS_US_PER_SEC, NULL))
128d4afb5ceSopenharmony_ci		goto cdone;
129d4afb5ceSopenharmony_ci
130d4afb5ceSopenharmony_ci	if (lws_cache_write_through(l1, "b", (const uint8_t *)"is_b", 5,
131d4afb5ceSopenharmony_ci				    lws_now_usecs() + LWS_US_PER_SEC * 2, NULL))
132d4afb5ceSopenharmony_ci		goto cdone;
133d4afb5ceSopenharmony_ci
134d4afb5ceSopenharmony_ci	/* only b should exit, since we limit to cache to just one entry */
135d4afb5ceSopenharmony_ci
136d4afb5ceSopenharmony_ci	if (!lws_cache_item_get(l1, "a", (const void **)&po, &size))
137d4afb5ceSopenharmony_ci		goto cdone;
138d4afb5ceSopenharmony_ci
139d4afb5ceSopenharmony_ci	if (lws_cache_item_get(l1, "b", (const void **)&po, &size) ||
140d4afb5ceSopenharmony_ci	    size != 5 || strcmp(po, "is_b"))
141d4afb5ceSopenharmony_ci		goto cdone;
142d4afb5ceSopenharmony_ci
143d4afb5ceSopenharmony_ci	/* that's ok then */
144d4afb5ceSopenharmony_ci
145d4afb5ceSopenharmony_ci	ret = 0;
146d4afb5ceSopenharmony_ci
147d4afb5ceSopenharmony_cicdone:
148d4afb5ceSopenharmony_ci	lws_cache_destroy(&l1);
149d4afb5ceSopenharmony_ci
150d4afb5ceSopenharmony_ci	if (ret)
151d4afb5ceSopenharmony_ci		lwsl_warn("%s: fail\n", __func__);
152d4afb5ceSopenharmony_ci
153d4afb5ceSopenharmony_ci	return ret;
154d4afb5ceSopenharmony_ci}
155d4afb5ceSopenharmony_ci
156d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CACHE_NSCOOKIEJAR)
157d4afb5ceSopenharmony_ci
158d4afb5ceSopenharmony_cistatic const char
159d4afb5ceSopenharmony_ci	*cookie1 = "host.com\tFALSE\t/\tTRUE\t4000000000\tmycookie\tmycookievalue",
160d4afb5ceSopenharmony_ci	*tag_cookie1 = "host.com|/|mycookie",
161d4afb5ceSopenharmony_ci	*cookie2 = "host.com\tFALSE\t/xxx\tTRUE\t4000000000\tmycookie\tmyxxxcookievalue",
162d4afb5ceSopenharmony_ci	*tag_cookie2 = "host.com|/xxx|mycookie",
163d4afb5ceSopenharmony_ci	*cookie3 = "host.com\tFALSE\t/\tTRUE\t4000000000\textra\tcookie3value",
164d4afb5ceSopenharmony_ci	*tag_cookie3 = "host.com|/|extra",
165d4afb5ceSopenharmony_ci	*cookie4 = "host.com\tFALSE\t/yyy\tTRUE\t4000000000\tnewcookie\tnewcookievalue",
166d4afb5ceSopenharmony_ci	*tag_cookie4 = "host.com|/yyy|newcookie"
167d4afb5ceSopenharmony_ci;
168d4afb5ceSopenharmony_ci
169d4afb5ceSopenharmony_cistatic int
170d4afb5ceSopenharmony_citest_nsc1(void)
171d4afb5ceSopenharmony_ci{
172d4afb5ceSopenharmony_ci	struct lws_cache_creation_info ci;
173d4afb5ceSopenharmony_ci	struct lws_cache_ttl_lru *l1 = NULL, *nsc;
174d4afb5ceSopenharmony_ci	lws_cache_results_t cr;
175d4afb5ceSopenharmony_ci	int n, ret = 1;
176d4afb5ceSopenharmony_ci	size_t size;
177d4afb5ceSopenharmony_ci	char *po;
178d4afb5ceSopenharmony_ci
179d4afb5ceSopenharmony_ci	lwsl_user("%s\n", __func__);
180d4afb5ceSopenharmony_ci	tests++;
181d4afb5ceSopenharmony_ci
182d4afb5ceSopenharmony_ci	/* First create a netscape cookie cache object */
183d4afb5ceSopenharmony_ci
184d4afb5ceSopenharmony_ci	memset(&ci, 0, sizeof(ci));
185d4afb5ceSopenharmony_ci	ci.cx = cx;
186d4afb5ceSopenharmony_ci	ci.ops = &lws_cache_ops_nscookiejar;
187d4afb5ceSopenharmony_ci	ci.name = "NSC";
188d4afb5ceSopenharmony_ci	ci.u.nscookiejar.filepath = "./cookies.txt";
189d4afb5ceSopenharmony_ci
190d4afb5ceSopenharmony_ci	nsc = lws_cache_create(&ci);
191d4afb5ceSopenharmony_ci	if (!nsc)
192d4afb5ceSopenharmony_ci		goto cdone;
193d4afb5ceSopenharmony_ci
194d4afb5ceSopenharmony_ci	/* Then a heap cache "L1" as a child of nsc */
195d4afb5ceSopenharmony_ci
196d4afb5ceSopenharmony_ci	ci.ops = &lws_cache_ops_heap;
197d4afb5ceSopenharmony_ci	ci.name = "L1";
198d4afb5ceSopenharmony_ci	ci.parent = nsc;
199d4afb5ceSopenharmony_ci
200d4afb5ceSopenharmony_ci	l1 = lws_cache_create(&ci);
201d4afb5ceSopenharmony_ci	if (!l1)
202d4afb5ceSopenharmony_ci		goto cdone;
203d4afb5ceSopenharmony_ci
204d4afb5ceSopenharmony_ci	lws_cache_debug_dump(nsc);
205d4afb5ceSopenharmony_ci	lws_cache_debug_dump(l1);
206d4afb5ceSopenharmony_ci
207d4afb5ceSopenharmony_ci	lwsl_user("%s: add cookies to L1\n", __func__);
208d4afb5ceSopenharmony_ci
209d4afb5ceSopenharmony_ci	/* add three cookies */
210d4afb5ceSopenharmony_ci
211d4afb5ceSopenharmony_ci	if (lws_cache_write_through(l1, tag_cookie1,
212d4afb5ceSopenharmony_ci				    (const uint8_t *)cookie1, strlen(cookie1),
213d4afb5ceSopenharmony_ci				    lws_now_usecs() + LWS_US_PER_SEC, NULL)) {
214d4afb5ceSopenharmony_ci		lwsl_err("%s: write1 failed\n", __func__);
215d4afb5ceSopenharmony_ci		goto cdone;
216d4afb5ceSopenharmony_ci	}
217d4afb5ceSopenharmony_ci
218d4afb5ceSopenharmony_ci	lws_cache_debug_dump(nsc);
219d4afb5ceSopenharmony_ci	lws_cache_debug_dump(l1);
220d4afb5ceSopenharmony_ci
221d4afb5ceSopenharmony_ci	if (lws_cache_write_through(l1, tag_cookie2,
222d4afb5ceSopenharmony_ci				    (const uint8_t *)cookie2, strlen(cookie2),
223d4afb5ceSopenharmony_ci				    lws_now_usecs() + LWS_US_PER_SEC * 2, NULL)) {
224d4afb5ceSopenharmony_ci		lwsl_err("%s: write2 failed\n", __func__);
225d4afb5ceSopenharmony_ci		goto cdone;
226d4afb5ceSopenharmony_ci	}
227d4afb5ceSopenharmony_ci
228d4afb5ceSopenharmony_ci	lws_cache_debug_dump(nsc);
229d4afb5ceSopenharmony_ci	lws_cache_debug_dump(l1);
230d4afb5ceSopenharmony_ci
231d4afb5ceSopenharmony_ci	if (lws_cache_write_through(l1, tag_cookie3,
232d4afb5ceSopenharmony_ci				    (const uint8_t *)cookie3, strlen(cookie3),
233d4afb5ceSopenharmony_ci				    lws_now_usecs() + LWS_US_PER_SEC * 2, NULL)) {
234d4afb5ceSopenharmony_ci		lwsl_err("%s: write3 failed\n", __func__);
235d4afb5ceSopenharmony_ci		goto cdone;
236d4afb5ceSopenharmony_ci	}
237d4afb5ceSopenharmony_ci
238d4afb5ceSopenharmony_ci	lws_cache_debug_dump(nsc);
239d4afb5ceSopenharmony_ci	lws_cache_debug_dump(l1);
240d4afb5ceSopenharmony_ci
241d4afb5ceSopenharmony_ci	lwsl_user("%s: check cookies in L1\n", __func__);
242d4afb5ceSopenharmony_ci
243d4afb5ceSopenharmony_ci	/* confirm that the cookies are individually in L1 */
244d4afb5ceSopenharmony_ci
245d4afb5ceSopenharmony_ci	if (lws_cache_item_get(l1, tag_cookie1, (const void **)&po, &size) ||
246d4afb5ceSopenharmony_ci	    size != strlen(cookie1) || memcmp(po, cookie1, size)) {
247d4afb5ceSopenharmony_ci		lwsl_err("%s: L1 '%s' missing, size %llu, po %s\n", __func__,
248d4afb5ceSopenharmony_ci			 tag_cookie1, (unsigned long long)size, po);
249d4afb5ceSopenharmony_ci		goto cdone;
250d4afb5ceSopenharmony_ci	}
251d4afb5ceSopenharmony_ci
252d4afb5ceSopenharmony_ci	if (lws_cache_item_get(l1, tag_cookie2, (const void **)&po, &size) ||
253d4afb5ceSopenharmony_ci	    size != strlen(cookie2) || memcmp(po, cookie2, size)) {
254d4afb5ceSopenharmony_ci		lwsl_err("%s: L1 '%s' missing\n", __func__, tag_cookie2);
255d4afb5ceSopenharmony_ci		goto cdone;
256d4afb5ceSopenharmony_ci	}
257d4afb5ceSopenharmony_ci
258d4afb5ceSopenharmony_ci	if (lws_cache_item_get(l1, tag_cookie3, (const void **)&po, &size) ||
259d4afb5ceSopenharmony_ci	    size != strlen(cookie3) || memcmp(po, cookie3, size)) {
260d4afb5ceSopenharmony_ci		lwsl_err("%s: L1 '%s' missing\n", __func__, tag_cookie3);
261d4afb5ceSopenharmony_ci		goto cdone;
262d4afb5ceSopenharmony_ci	}
263d4afb5ceSopenharmony_ci
264d4afb5ceSopenharmony_ci	/* confirm that the cookies are individually in L2 / NSC... normally
265d4afb5ceSopenharmony_ci	 * we don't do this but check via L1 so we can get it from there if
266d4afb5ceSopenharmony_ci	 * present.  But as a unit test, we want to make sure it's in L2 / NSC
267d4afb5ceSopenharmony_ci	 */
268d4afb5ceSopenharmony_ci
269d4afb5ceSopenharmony_ci	lwsl_user("%s: check cookies written thru to NSC\n", __func__);
270d4afb5ceSopenharmony_ci
271d4afb5ceSopenharmony_ci	if (lws_cache_item_get(nsc, tag_cookie1, (const void **)&po, &size) ||
272d4afb5ceSopenharmony_ci	    size != strlen(cookie1) || memcmp(po, cookie1, size)) {
273d4afb5ceSopenharmony_ci		lwsl_err("%s: NSC '%s' missing, size %llu, po %s\n", __func__,
274d4afb5ceSopenharmony_ci			 tag_cookie1, (unsigned long long)size, po);
275d4afb5ceSopenharmony_ci		goto cdone;
276d4afb5ceSopenharmony_ci	}
277d4afb5ceSopenharmony_ci
278d4afb5ceSopenharmony_ci	if (lws_cache_item_get(nsc, tag_cookie2, (const void **)&po, &size) ||
279d4afb5ceSopenharmony_ci	    size != strlen(cookie2) || memcmp(po, cookie2, size)) {
280d4afb5ceSopenharmony_ci		lwsl_err("%s: NSC '%s' missing\n", __func__, tag_cookie2);
281d4afb5ceSopenharmony_ci		goto cdone;
282d4afb5ceSopenharmony_ci	}
283d4afb5ceSopenharmony_ci
284d4afb5ceSopenharmony_ci	if (lws_cache_item_get(nsc, tag_cookie3, (const void **)&po, &size) ||
285d4afb5ceSopenharmony_ci	    size != strlen(cookie3) || memcmp(po, cookie3, size)) {
286d4afb5ceSopenharmony_ci		lwsl_err("%s: NSC '%s' missing\n", __func__, tag_cookie3);
287d4afb5ceSopenharmony_ci		goto cdone;
288d4afb5ceSopenharmony_ci	}
289d4afb5ceSopenharmony_ci
290d4afb5ceSopenharmony_ci	/* let's do a lookup with no results */
291d4afb5ceSopenharmony_ci
292d4afb5ceSopenharmony_ci	lwsl_user("%s: nonexistant get must not pass\n", __func__);
293d4afb5ceSopenharmony_ci
294d4afb5ceSopenharmony_ci	if (!lws_cache_item_get(l1, "x.com|y|z", (const void **)&po, &size)) {
295d4afb5ceSopenharmony_ci		lwsl_err("%s: nonexistant found size %llu, po %s\n", __func__,
296d4afb5ceSopenharmony_ci			 (unsigned long long)size, po);
297d4afb5ceSopenharmony_ci		goto cdone;
298d4afb5ceSopenharmony_ci	}
299d4afb5ceSopenharmony_ci
300d4afb5ceSopenharmony_ci	/*
301d4afb5ceSopenharmony_ci	 * let's try some url paths and check we get the right results set...
302d4afb5ceSopenharmony_ci	 * for / and any cookie, we expect only c1 and c3 to be listed
303d4afb5ceSopenharmony_ci	 */
304d4afb5ceSopenharmony_ci
305d4afb5ceSopenharmony_ci	lwsl_user("%s: wildcard lookup 1\n", __func__);
306d4afb5ceSopenharmony_ci
307d4afb5ceSopenharmony_ci	n = lws_cache_lookup(l1, "host.com|/|*",
308d4afb5ceSopenharmony_ci			     (const void **)&cr.ptr, &cr.size);
309d4afb5ceSopenharmony_ci	if (n) {
310d4afb5ceSopenharmony_ci		lwsl_err("%s: lookup failed %d\n", __func__, n);
311d4afb5ceSopenharmony_ci		goto cdone;
312d4afb5ceSopenharmony_ci	}
313d4afb5ceSopenharmony_ci	lwsl_hexdump_notice(cr.ptr, size);
314d4afb5ceSopenharmony_ci
315d4afb5ceSopenharmony_ci	if (cr.size != 53)
316d4afb5ceSopenharmony_ci		goto cdone;
317d4afb5ceSopenharmony_ci
318d4afb5ceSopenharmony_ci	while (!lws_cache_results_walk(&cr))
319d4afb5ceSopenharmony_ci		lwsl_notice("  %s (%d)\n", (const char *)cr.tag,
320d4afb5ceSopenharmony_ci					   (int)cr.payload_len);
321d4afb5ceSopenharmony_ci
322d4afb5ceSopenharmony_ci	/*
323d4afb5ceSopenharmony_ci	 * for /xxx and any cookie, we expect all 3 listed
324d4afb5ceSopenharmony_ci	 */
325d4afb5ceSopenharmony_ci
326d4afb5ceSopenharmony_ci	lwsl_user("%s: wildcard lookup 2\n", __func__);
327d4afb5ceSopenharmony_ci
328d4afb5ceSopenharmony_ci	n = lws_cache_lookup(l1, "host.com|/xxx|*",
329d4afb5ceSopenharmony_ci			     (const void **)&cr.ptr, &cr.size);
330d4afb5ceSopenharmony_ci	if (n) {
331d4afb5ceSopenharmony_ci		lwsl_err("%s: lookup failed %d\n", __func__, n);
332d4afb5ceSopenharmony_ci		goto cdone;
333d4afb5ceSopenharmony_ci	}
334d4afb5ceSopenharmony_ci
335d4afb5ceSopenharmony_ci	if (cr.size != 84)
336d4afb5ceSopenharmony_ci		goto cdone;
337d4afb5ceSopenharmony_ci
338d4afb5ceSopenharmony_ci	while (!lws_cache_results_walk(&cr))
339d4afb5ceSopenharmony_ci		lwsl_notice("  %s (%d)\n", (const char *)cr.tag,
340d4afb5ceSopenharmony_ci					   (int)cr.payload_len);
341d4afb5ceSopenharmony_ci
342d4afb5ceSopenharmony_ci	/*
343d4afb5ceSopenharmony_ci	 * for /yyyy and any cookie, we expect only c1 and c3
344d4afb5ceSopenharmony_ci	 */
345d4afb5ceSopenharmony_ci
346d4afb5ceSopenharmony_ci	lwsl_user("%s: wildcard lookup 3\n", __func__);
347d4afb5ceSopenharmony_ci
348d4afb5ceSopenharmony_ci	n = lws_cache_lookup(l1, "host.com|/yyyy|*",
349d4afb5ceSopenharmony_ci			     (const void **)&cr.ptr, &cr.size);
350d4afb5ceSopenharmony_ci	if (n) {
351d4afb5ceSopenharmony_ci		lwsl_err("%s: lookup failed %d\n", __func__, n);
352d4afb5ceSopenharmony_ci		goto cdone;
353d4afb5ceSopenharmony_ci	}
354d4afb5ceSopenharmony_ci
355d4afb5ceSopenharmony_ci	if (cr.size != 53)
356d4afb5ceSopenharmony_ci		goto cdone;
357d4afb5ceSopenharmony_ci
358d4afb5ceSopenharmony_ci	while (!lws_cache_results_walk(&cr))
359d4afb5ceSopenharmony_ci		lwsl_notice("  %s (%d)\n", (const char *)cr.tag,
360d4afb5ceSopenharmony_ci					   (int)cr.payload_len);
361d4afb5ceSopenharmony_ci
362d4afb5ceSopenharmony_ci	/*
363d4afb5ceSopenharmony_ci	 * repeat the above test, results should come from cache
364d4afb5ceSopenharmony_ci	 */
365d4afb5ceSopenharmony_ci
366d4afb5ceSopenharmony_ci	lwsl_user("%s: wildcard lookup 4\n", __func__);
367d4afb5ceSopenharmony_ci
368d4afb5ceSopenharmony_ci	n = lws_cache_lookup(l1, "host.com|/yyyy|*",
369d4afb5ceSopenharmony_ci			     (const void **)&cr.ptr, &cr.size);
370d4afb5ceSopenharmony_ci	if (n) {
371d4afb5ceSopenharmony_ci		lwsl_err("%s: lookup failed %d\n", __func__, n);
372d4afb5ceSopenharmony_ci		goto cdone;
373d4afb5ceSopenharmony_ci	}
374d4afb5ceSopenharmony_ci
375d4afb5ceSopenharmony_ci	if (cr.size != 53)
376d4afb5ceSopenharmony_ci		goto cdone;
377d4afb5ceSopenharmony_ci
378d4afb5ceSopenharmony_ci	while (!lws_cache_results_walk(&cr))
379d4afb5ceSopenharmony_ci		lwsl_notice("  %s (%d)\n", (const char *)cr.tag,
380d4afb5ceSopenharmony_ci					   (int)cr.payload_len);
381d4afb5ceSopenharmony_ci
382d4afb5ceSopenharmony_ci	/* now let's try deleting cookie 1 */
383d4afb5ceSopenharmony_ci
384d4afb5ceSopenharmony_ci	if (lws_cache_item_remove(l1, tag_cookie1))
385d4afb5ceSopenharmony_ci		goto cdone;
386d4afb5ceSopenharmony_ci
387d4afb5ceSopenharmony_ci	lws_cache_debug_dump(nsc);
388d4afb5ceSopenharmony_ci	lws_cache_debug_dump(l1);
389d4afb5ceSopenharmony_ci
390d4afb5ceSopenharmony_ci	/* with c1 gone, we should only get c3 */
391d4afb5ceSopenharmony_ci
392d4afb5ceSopenharmony_ci	lwsl_user("%s: wildcard lookup 5\n", __func__);
393d4afb5ceSopenharmony_ci
394d4afb5ceSopenharmony_ci	n = lws_cache_lookup(l1, "host.com|/|*",
395d4afb5ceSopenharmony_ci			     (const void **)&cr.ptr, &cr.size);
396d4afb5ceSopenharmony_ci	if (n) {
397d4afb5ceSopenharmony_ci		lwsl_err("%s: lookup failed %d\n", __func__, n);
398d4afb5ceSopenharmony_ci		goto cdone;
399d4afb5ceSopenharmony_ci	}
400d4afb5ceSopenharmony_ci
401d4afb5ceSopenharmony_ci	if (cr.size != 25)
402d4afb5ceSopenharmony_ci		goto cdone;
403d4afb5ceSopenharmony_ci
404d4afb5ceSopenharmony_ci	while (!lws_cache_results_walk(&cr))
405d4afb5ceSopenharmony_ci		lwsl_notice("  %s (%d)\n", (const char *)cr.tag,
406d4afb5ceSopenharmony_ci					   (int)cr.payload_len);
407d4afb5ceSopenharmony_ci
408d4afb5ceSopenharmony_ci	/*
409d4afb5ceSopenharmony_ci	 * let's add a fourth cookie (third in cache now we deleted one)
410d4afb5ceSopenharmony_ci	 */
411d4afb5ceSopenharmony_ci
412d4afb5ceSopenharmony_ci	if (lws_cache_write_through(l1, tag_cookie4,
413d4afb5ceSopenharmony_ci				    (const uint8_t *)cookie4, strlen(cookie4),
414d4afb5ceSopenharmony_ci				    lws_now_usecs() + LWS_US_PER_SEC * 2, NULL)) {
415d4afb5ceSopenharmony_ci		lwsl_err("%s: write4 failed\n", __func__);
416d4afb5ceSopenharmony_ci		goto cdone;
417d4afb5ceSopenharmony_ci	}
418d4afb5ceSopenharmony_ci
419d4afb5ceSopenharmony_ci	/*
420d4afb5ceSopenharmony_ci	 * for /yy and any cookie, we expect only c3
421d4afb5ceSopenharmony_ci	 */
422d4afb5ceSopenharmony_ci
423d4afb5ceSopenharmony_ci	lwsl_user("%s: wildcard lookup 6\n", __func__);
424d4afb5ceSopenharmony_ci
425d4afb5ceSopenharmony_ci	n = lws_cache_lookup(l1, "host.com|/yy|*",
426d4afb5ceSopenharmony_ci			     (const void **)&cr.ptr, &cr.size);
427d4afb5ceSopenharmony_ci	if (n) {
428d4afb5ceSopenharmony_ci		lwsl_err("%s: lookup failed %d\n", __func__, n);
429d4afb5ceSopenharmony_ci		goto cdone;
430d4afb5ceSopenharmony_ci	}
431d4afb5ceSopenharmony_ci
432d4afb5ceSopenharmony_ci	if (cr.size != 25)
433d4afb5ceSopenharmony_ci		goto cdone;
434d4afb5ceSopenharmony_ci
435d4afb5ceSopenharmony_ci	while (!lws_cache_results_walk(&cr))
436d4afb5ceSopenharmony_ci		lwsl_notice("  %s (%d)\n", (const char *)cr.tag,
437d4afb5ceSopenharmony_ci					   (int)cr.payload_len);
438d4afb5ceSopenharmony_ci
439d4afb5ceSopenharmony_ci	/*
440d4afb5ceSopenharmony_ci	 * for /yyy and any cookie, we expect  c3 and c4
441d4afb5ceSopenharmony_ci	 */
442d4afb5ceSopenharmony_ci
443d4afb5ceSopenharmony_ci	lwsl_user("%s: wildcard lookup 7\n", __func__);
444d4afb5ceSopenharmony_ci
445d4afb5ceSopenharmony_ci	n = lws_cache_lookup(l1, "host.com|/yyy|*",
446d4afb5ceSopenharmony_ci			     (const void **)&cr.ptr, &cr.size);
447d4afb5ceSopenharmony_ci	if (n) {
448d4afb5ceSopenharmony_ci		lwsl_err("%s: lookup failed %d\n", __func__, n);
449d4afb5ceSopenharmony_ci		goto cdone;
450d4afb5ceSopenharmony_ci	}
451d4afb5ceSopenharmony_ci
452d4afb5ceSopenharmony_ci	if (cr.size != 57)
453d4afb5ceSopenharmony_ci		goto cdone;
454d4afb5ceSopenharmony_ci
455d4afb5ceSopenharmony_ci	while (!lws_cache_results_walk(&cr))
456d4afb5ceSopenharmony_ci		lwsl_notice("  %s (%d)\n", (const char *)cr.tag,
457d4afb5ceSopenharmony_ci					   (int)cr.payload_len);
458d4afb5ceSopenharmony_ci
459d4afb5ceSopenharmony_ci	/* that's ok then */
460d4afb5ceSopenharmony_ci
461d4afb5ceSopenharmony_ci	lwsl_user("%s: done\n", __func__);
462d4afb5ceSopenharmony_ci
463d4afb5ceSopenharmony_ci	ret = 0;
464d4afb5ceSopenharmony_ci
465d4afb5ceSopenharmony_cicdone:
466d4afb5ceSopenharmony_ci	lws_cache_destroy(&nsc);
467d4afb5ceSopenharmony_ci	lws_cache_destroy(&l1);
468d4afb5ceSopenharmony_ci
469d4afb5ceSopenharmony_ci	if (ret)
470d4afb5ceSopenharmony_ci		lwsl_warn("%s: fail\n", __func__);
471d4afb5ceSopenharmony_ci
472d4afb5ceSopenharmony_ci	return ret;
473d4afb5ceSopenharmony_ci}
474d4afb5ceSopenharmony_ci#endif
475d4afb5ceSopenharmony_ci
476d4afb5ceSopenharmony_ci
477d4afb5ceSopenharmony_ciint main(int argc, const char **argv)
478d4afb5ceSopenharmony_ci{
479d4afb5ceSopenharmony_ci	struct lws_context_creation_info info;
480d4afb5ceSopenharmony_ci
481d4afb5ceSopenharmony_ci	memset(&info, 0, sizeof info);
482d4afb5ceSopenharmony_ci	lws_cmdline_option_handle_builtin(argc, argv, &info);
483d4afb5ceSopenharmony_ci	info.fd_limit_per_thread = 1 + 6 + 1;
484d4afb5ceSopenharmony_ci	info.port = CONTEXT_PORT_NO_LISTEN;
485d4afb5ceSopenharmony_ci
486d4afb5ceSopenharmony_ci	lwsl_user("LWS API selftest: lws_cache\n");
487d4afb5ceSopenharmony_ci
488d4afb5ceSopenharmony_ci	cx = lws_create_context(&info);
489d4afb5ceSopenharmony_ci	if (!cx) {
490d4afb5ceSopenharmony_ci		lwsl_err("lws init failed\n");
491d4afb5ceSopenharmony_ci		return 1;
492d4afb5ceSopenharmony_ci	}
493d4afb5ceSopenharmony_ci
494d4afb5ceSopenharmony_ci	if (test_just_l1())
495d4afb5ceSopenharmony_ci		fail++;
496d4afb5ceSopenharmony_ci	if (test_just_l1_limits())
497d4afb5ceSopenharmony_ci		fail++;
498d4afb5ceSopenharmony_ci
499d4afb5ceSopenharmony_ci#if defined(LWS_WITH_CACHE_NSCOOKIEJAR)
500d4afb5ceSopenharmony_ci	if (test_nsc1())
501d4afb5ceSopenharmony_ci		fail++;
502d4afb5ceSopenharmony_ci#endif
503d4afb5ceSopenharmony_ci
504d4afb5ceSopenharmony_ci	lws_context_destroy(cx);
505d4afb5ceSopenharmony_ci
506d4afb5ceSopenharmony_ci	if (tests && !fail)
507d4afb5ceSopenharmony_ci		lwsl_user("Completed: PASS\n");
508d4afb5ceSopenharmony_ci	else
509d4afb5ceSopenharmony_ci		lwsl_err("Completed: FAIL %d / %d\n", fail, tests);
510d4afb5ceSopenharmony_ci
511d4afb5ceSopenharmony_ci	return 0;
512d4afb5ceSopenharmony_ci}
513