1 | /*************************************************************************** |
2 | * _ _ ____ _ |
3 | * Project ___| | | | _ \| | |
4 | * / __| | | | |_) | | |
5 | * | (__| |_| | _ <| |___ |
6 | * \___|\___/|_| \_\_____| |
7 | * |
8 | * Copyright (C) 2020 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. |
9 | * |
10 | * This software is licensed as described in the file COPYING, which |
11 | * you should have received as part of this distribution. The terms |
12 | * are also available at https://curl.se/docs/copyright.html. |
13 | * |
14 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
15 | * copies of the Software, and permit persons to whom the Software is |
16 | * furnished to do so, under the terms of the COPYING file. |
17 | * |
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
19 | * KIND, either express or implied. |
20 | * |
21 | ***************************************************************************/ |
22 | #include "test.h" |
23 | |
24 | #include "testutil.h" |
25 | #include "warnless.h" |
26 | #include "memdebug.h" |
27 | |
28 | struct entry { |
29 | const char *name; |
30 | const char *exp; |
31 | }; |
32 | |
33 | static struct entry preload_hosts[] = { |
34 | /* curl turns 39 that day just before 31-bit time_t overflow */ |
35 | { "1.example.com" , "20370320 01:02:03" }, |
36 | { "2.example.com" , "20370320 03:02:01" }, |
37 | { "3.example.com" , "20370319 01:02:03" }, |
38 | { "4.example.com" , "" }, |
39 | { NULL, NULL } /* end of list marker */ |
40 | }; |
41 | |
42 | struct state { |
43 | int index; |
44 | }; |
45 | |
46 | /* "read" is from the point of the library, it wants data from us */ |
47 | static CURLSTScode hstsread(CURL *easy, struct curl_hstsentry *e, |
48 | void *userp) |
49 | { |
50 | const char *host; |
51 | const char *expire; |
52 | struct state *s = (struct state *)userp; |
53 | (void)easy; |
54 | host = preload_hosts[s->index].name; |
55 | expire = preload_hosts[s->index++].exp; |
56 | |
57 | if(host && (strlen(host) < e->namelen)) { |
58 | strcpy(e->name, host); |
59 | e->includeSubDomains = FALSE; |
60 | strcpy(e->expire, expire); |
61 | fprintf(stderr, "add '%s'\n" , host); |
62 | } |
63 | else |
64 | return CURLSTS_DONE; |
65 | return CURLSTS_OK; |
66 | } |
67 | |
68 | /* verify error from callback */ |
69 | static CURLSTScode hstsreadfail(CURL *easy, struct curl_hstsentry *e, |
70 | void *userp) |
71 | { |
72 | (void)easy; |
73 | (void)e; |
74 | (void)userp; |
75 | return CURLSTS_FAIL; |
76 | } |
77 | |
78 | /* check that we get the hosts back in the save */ |
79 | static CURLSTScode hstswrite(CURL *easy, struct curl_hstsentry *e, |
80 | struct curl_index *i, void *userp) |
81 | { |
82 | (void)easy; |
83 | (void)userp; |
84 | printf("[%zu/%zu] %s %s\n" , i->index, i->total, e->name, e->expire); |
85 | return CURLSTS_OK; |
86 | } |
87 | |
88 | /* |
89 | * Read/write HSTS cache entries via callback. |
90 | */ |
91 | |
92 | int test(char *URL) |
93 | { |
94 | CURLcode ret = CURLE_OK; |
95 | CURL *hnd; |
96 | struct state st = {0}; |
97 | |
98 | curl_global_init(CURL_GLOBAL_ALL); |
99 | |
100 | hnd = curl_easy_init(); |
101 | if(hnd) { |
102 | curl_easy_setopt(hnd, CURLOPT_URL, URL); |
103 | curl_easy_setopt(hnd, CURLOPT_HSTSREADFUNCTION, hstsread); |
104 | curl_easy_setopt(hnd, CURLOPT_HSTSREADDATA, &st); |
105 | curl_easy_setopt(hnd, CURLOPT_HSTSWRITEFUNCTION, hstswrite); |
106 | curl_easy_setopt(hnd, CURLOPT_HSTSWRITEDATA, &st); |
107 | curl_easy_setopt(hnd, CURLOPT_HSTS_CTRL, CURLHSTS_ENABLE); |
108 | ret = curl_easy_perform(hnd); |
109 | curl_easy_cleanup(hnd); |
110 | printf("First request returned %d\n" , (int)ret); |
111 | } |
112 | hnd = curl_easy_init(); |
113 | if(hnd) { |
114 | curl_easy_setopt(hnd, CURLOPT_URL, URL); |
115 | curl_easy_setopt(hnd, CURLOPT_HSTSREADFUNCTION, hstsreadfail); |
116 | curl_easy_setopt(hnd, CURLOPT_HSTSREADDATA, &st); |
117 | curl_easy_setopt(hnd, CURLOPT_HSTSWRITEFUNCTION, hstswrite); |
118 | curl_easy_setopt(hnd, CURLOPT_HSTSWRITEDATA, &st); |
119 | curl_easy_setopt(hnd, CURLOPT_HSTS_CTRL, CURLHSTS_ENABLE); |
120 | ret = curl_easy_perform(hnd); |
121 | curl_easy_cleanup(hnd); |
122 | printf("Second request returned %d\n" , (int)ret); |
123 | } |
124 | curl_global_cleanup(); |
125 | return (int)ret; |
126 | } |
127 | |