xref: /aosp_15_r20/external/curl/src/tool_ipfs.c (revision 6236dae45794135f37c4eb022389c904c8b0090d)
1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker  *                                  _   _ ____  _
3*6236dae4SAndroid Build Coastguard Worker  *  Project                     ___| | | |  _ \| |
4*6236dae4SAndroid Build Coastguard Worker  *                             / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker  *                            | (__| |_| |  _ <| |___
6*6236dae4SAndroid Build Coastguard Worker  *                             \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker  *
8*6236dae4SAndroid Build Coastguard Worker  * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker  *
10*6236dae4SAndroid Build Coastguard Worker  * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker  * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker  * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker  *
14*6236dae4SAndroid Build Coastguard Worker  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker  * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker  * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker  *
18*6236dae4SAndroid Build Coastguard Worker  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker  * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker  *
21*6236dae4SAndroid Build Coastguard Worker  * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker  *
23*6236dae4SAndroid Build Coastguard Worker  ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker #include "tool_setup.h"
25*6236dae4SAndroid Build Coastguard Worker 
26*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_DISABLE_IPFS
27*6236dae4SAndroid Build Coastguard Worker #include "curlx.h"
28*6236dae4SAndroid Build Coastguard Worker #include "dynbuf.h"
29*6236dae4SAndroid Build Coastguard Worker 
30*6236dae4SAndroid Build Coastguard Worker #include "tool_cfgable.h"
31*6236dae4SAndroid Build Coastguard Worker #include "tool_msgs.h"
32*6236dae4SAndroid Build Coastguard Worker #include "tool_ipfs.h"
33*6236dae4SAndroid Build Coastguard Worker 
34*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h" /* keep this as LAST include */
35*6236dae4SAndroid Build Coastguard Worker 
36*6236dae4SAndroid Build Coastguard Worker /* ensure input ends in slash */
ensure_trailing_slash(char ** input)37*6236dae4SAndroid Build Coastguard Worker static CURLcode ensure_trailing_slash(char **input)
38*6236dae4SAndroid Build Coastguard Worker {
39*6236dae4SAndroid Build Coastguard Worker   if(*input && **input) {
40*6236dae4SAndroid Build Coastguard Worker     size_t len = strlen(*input);
41*6236dae4SAndroid Build Coastguard Worker     if(((*input)[len - 1] != '/')) {
42*6236dae4SAndroid Build Coastguard Worker       struct curlx_dynbuf dyn;
43*6236dae4SAndroid Build Coastguard Worker       curlx_dyn_init(&dyn, len + 2);
44*6236dae4SAndroid Build Coastguard Worker 
45*6236dae4SAndroid Build Coastguard Worker       if(curlx_dyn_addn(&dyn, *input, len)) {
46*6236dae4SAndroid Build Coastguard Worker         Curl_safefree(*input);
47*6236dae4SAndroid Build Coastguard Worker         return CURLE_OUT_OF_MEMORY;
48*6236dae4SAndroid Build Coastguard Worker       }
49*6236dae4SAndroid Build Coastguard Worker 
50*6236dae4SAndroid Build Coastguard Worker       Curl_safefree(*input);
51*6236dae4SAndroid Build Coastguard Worker 
52*6236dae4SAndroid Build Coastguard Worker       if(curlx_dyn_addn(&dyn, "/", 1))
53*6236dae4SAndroid Build Coastguard Worker         return CURLE_OUT_OF_MEMORY;
54*6236dae4SAndroid Build Coastguard Worker 
55*6236dae4SAndroid Build Coastguard Worker       *input = curlx_dyn_ptr(&dyn);
56*6236dae4SAndroid Build Coastguard Worker     }
57*6236dae4SAndroid Build Coastguard Worker   }
58*6236dae4SAndroid Build Coastguard Worker 
59*6236dae4SAndroid Build Coastguard Worker   return CURLE_OK;
60*6236dae4SAndroid Build Coastguard Worker }
61*6236dae4SAndroid Build Coastguard Worker 
ipfs_gateway(void)62*6236dae4SAndroid Build Coastguard Worker static char *ipfs_gateway(void)
63*6236dae4SAndroid Build Coastguard Worker {
64*6236dae4SAndroid Build Coastguard Worker   char *ipfs_path = NULL;
65*6236dae4SAndroid Build Coastguard Worker   char *gateway_composed_file_path = NULL;
66*6236dae4SAndroid Build Coastguard Worker   FILE *gateway_file = NULL;
67*6236dae4SAndroid Build Coastguard Worker   char *gateway = curl_getenv("IPFS_GATEWAY");
68*6236dae4SAndroid Build Coastguard Worker 
69*6236dae4SAndroid Build Coastguard Worker   /* Gateway is found from environment variable. */
70*6236dae4SAndroid Build Coastguard Worker   if(gateway) {
71*6236dae4SAndroid Build Coastguard Worker     if(ensure_trailing_slash(&gateway))
72*6236dae4SAndroid Build Coastguard Worker       goto fail;
73*6236dae4SAndroid Build Coastguard Worker     return gateway;
74*6236dae4SAndroid Build Coastguard Worker   }
75*6236dae4SAndroid Build Coastguard Worker 
76*6236dae4SAndroid Build Coastguard Worker   /* Try to find the gateway in the IPFS data folder. */
77*6236dae4SAndroid Build Coastguard Worker   ipfs_path = curl_getenv("IPFS_PATH");
78*6236dae4SAndroid Build Coastguard Worker 
79*6236dae4SAndroid Build Coastguard Worker   if(!ipfs_path) {
80*6236dae4SAndroid Build Coastguard Worker     char *home = getenv("HOME");
81*6236dae4SAndroid Build Coastguard Worker     if(home && *home)
82*6236dae4SAndroid Build Coastguard Worker       ipfs_path = aprintf("%s/.ipfs/", home);
83*6236dae4SAndroid Build Coastguard Worker     /* fallback to "~/.ipfs", as that is the default location. */
84*6236dae4SAndroid Build Coastguard Worker   }
85*6236dae4SAndroid Build Coastguard Worker 
86*6236dae4SAndroid Build Coastguard Worker   if(!ipfs_path || ensure_trailing_slash(&ipfs_path))
87*6236dae4SAndroid Build Coastguard Worker     goto fail;
88*6236dae4SAndroid Build Coastguard Worker 
89*6236dae4SAndroid Build Coastguard Worker   gateway_composed_file_path = aprintf("%sgateway", ipfs_path);
90*6236dae4SAndroid Build Coastguard Worker 
91*6236dae4SAndroid Build Coastguard Worker   if(!gateway_composed_file_path)
92*6236dae4SAndroid Build Coastguard Worker     goto fail;
93*6236dae4SAndroid Build Coastguard Worker 
94*6236dae4SAndroid Build Coastguard Worker   gateway_file = fopen(gateway_composed_file_path, FOPEN_READTEXT);
95*6236dae4SAndroid Build Coastguard Worker   Curl_safefree(gateway_composed_file_path);
96*6236dae4SAndroid Build Coastguard Worker 
97*6236dae4SAndroid Build Coastguard Worker   if(gateway_file) {
98*6236dae4SAndroid Build Coastguard Worker     int c;
99*6236dae4SAndroid Build Coastguard Worker     struct curlx_dynbuf dyn;
100*6236dae4SAndroid Build Coastguard Worker     curlx_dyn_init(&dyn, MAX_GATEWAY_URL_LEN);
101*6236dae4SAndroid Build Coastguard Worker 
102*6236dae4SAndroid Build Coastguard Worker     /* get the first line of the gateway file, ignore the rest */
103*6236dae4SAndroid Build Coastguard Worker     while((c = getc(gateway_file)) != EOF && c != '\n' && c != '\r') {
104*6236dae4SAndroid Build Coastguard Worker       char c_char = (char)c;
105*6236dae4SAndroid Build Coastguard Worker       if(curlx_dyn_addn(&dyn, &c_char, 1))
106*6236dae4SAndroid Build Coastguard Worker         goto fail;
107*6236dae4SAndroid Build Coastguard Worker     }
108*6236dae4SAndroid Build Coastguard Worker 
109*6236dae4SAndroid Build Coastguard Worker     fclose(gateway_file);
110*6236dae4SAndroid Build Coastguard Worker     gateway_file = NULL;
111*6236dae4SAndroid Build Coastguard Worker 
112*6236dae4SAndroid Build Coastguard Worker     if(curlx_dyn_len(&dyn))
113*6236dae4SAndroid Build Coastguard Worker       gateway = curlx_dyn_ptr(&dyn);
114*6236dae4SAndroid Build Coastguard Worker 
115*6236dae4SAndroid Build Coastguard Worker     if(gateway)
116*6236dae4SAndroid Build Coastguard Worker       ensure_trailing_slash(&gateway);
117*6236dae4SAndroid Build Coastguard Worker 
118*6236dae4SAndroid Build Coastguard Worker     if(!gateway)
119*6236dae4SAndroid Build Coastguard Worker       goto fail;
120*6236dae4SAndroid Build Coastguard Worker 
121*6236dae4SAndroid Build Coastguard Worker     Curl_safefree(ipfs_path);
122*6236dae4SAndroid Build Coastguard Worker 
123*6236dae4SAndroid Build Coastguard Worker     return gateway;
124*6236dae4SAndroid Build Coastguard Worker   }
125*6236dae4SAndroid Build Coastguard Worker fail:
126*6236dae4SAndroid Build Coastguard Worker   if(gateway_file)
127*6236dae4SAndroid Build Coastguard Worker     fclose(gateway_file);
128*6236dae4SAndroid Build Coastguard Worker   Curl_safefree(gateway);
129*6236dae4SAndroid Build Coastguard Worker   Curl_safefree(ipfs_path);
130*6236dae4SAndroid Build Coastguard Worker   return NULL;
131*6236dae4SAndroid Build Coastguard Worker }
132*6236dae4SAndroid Build Coastguard Worker 
133*6236dae4SAndroid Build Coastguard Worker /*
134*6236dae4SAndroid Build Coastguard Worker  * Rewrite ipfs://<cid> and ipns://<cid> to an HTTP(S)
135*6236dae4SAndroid Build Coastguard Worker  * URL that can be handled by an IPFS gateway.
136*6236dae4SAndroid Build Coastguard Worker  */
ipfs_url_rewrite(CURLU * uh,const char * protocol,char ** url,struct OperationConfig * config)137*6236dae4SAndroid Build Coastguard Worker CURLcode ipfs_url_rewrite(CURLU *uh, const char *protocol, char **url,
138*6236dae4SAndroid Build Coastguard Worker                           struct OperationConfig *config)
139*6236dae4SAndroid Build Coastguard Worker {
140*6236dae4SAndroid Build Coastguard Worker   CURLcode result = CURLE_URL_MALFORMAT;
141*6236dae4SAndroid Build Coastguard Worker   CURLUcode getResult;
142*6236dae4SAndroid Build Coastguard Worker   char *gateway = NULL;
143*6236dae4SAndroid Build Coastguard Worker   char *gwhost = NULL;
144*6236dae4SAndroid Build Coastguard Worker   char *gwpath = NULL;
145*6236dae4SAndroid Build Coastguard Worker   char *gwquery = NULL;
146*6236dae4SAndroid Build Coastguard Worker   char *gwscheme = NULL;
147*6236dae4SAndroid Build Coastguard Worker   char *gwport = NULL;
148*6236dae4SAndroid Build Coastguard Worker   char *inputpath = NULL;
149*6236dae4SAndroid Build Coastguard Worker   char *cid = NULL;
150*6236dae4SAndroid Build Coastguard Worker   char *pathbuffer = NULL;
151*6236dae4SAndroid Build Coastguard Worker   char *cloneurl;
152*6236dae4SAndroid Build Coastguard Worker   CURLU *gatewayurl = curl_url();
153*6236dae4SAndroid Build Coastguard Worker 
154*6236dae4SAndroid Build Coastguard Worker   if(!gatewayurl) {
155*6236dae4SAndroid Build Coastguard Worker     result = CURLE_FAILED_INIT;
156*6236dae4SAndroid Build Coastguard Worker     goto clean;
157*6236dae4SAndroid Build Coastguard Worker   }
158*6236dae4SAndroid Build Coastguard Worker 
159*6236dae4SAndroid Build Coastguard Worker   getResult = curl_url_get(uh, CURLUPART_HOST, &cid, CURLU_URLDECODE);
160*6236dae4SAndroid Build Coastguard Worker   if(getResult || !cid)
161*6236dae4SAndroid Build Coastguard Worker     goto clean;
162*6236dae4SAndroid Build Coastguard Worker 
163*6236dae4SAndroid Build Coastguard Worker   /* We might have a --ipfs-gateway argument. Check it first and use it. Error
164*6236dae4SAndroid Build Coastguard Worker    * if we do have something but if it is an invalid url.
165*6236dae4SAndroid Build Coastguard Worker    */
166*6236dae4SAndroid Build Coastguard Worker   if(config->ipfs_gateway) {
167*6236dae4SAndroid Build Coastguard Worker     /* ensure the gateway ends in a trailing / */
168*6236dae4SAndroid Build Coastguard Worker     if(ensure_trailing_slash(&config->ipfs_gateway) != CURLE_OK) {
169*6236dae4SAndroid Build Coastguard Worker       result = CURLE_OUT_OF_MEMORY;
170*6236dae4SAndroid Build Coastguard Worker       goto clean;
171*6236dae4SAndroid Build Coastguard Worker     }
172*6236dae4SAndroid Build Coastguard Worker 
173*6236dae4SAndroid Build Coastguard Worker     if(!curl_url_set(gatewayurl, CURLUPART_URL, config->ipfs_gateway,
174*6236dae4SAndroid Build Coastguard Worker                     CURLU_GUESS_SCHEME)) {
175*6236dae4SAndroid Build Coastguard Worker       gateway = strdup(config->ipfs_gateway);
176*6236dae4SAndroid Build Coastguard Worker       if(!gateway) {
177*6236dae4SAndroid Build Coastguard Worker         result = CURLE_URL_MALFORMAT;
178*6236dae4SAndroid Build Coastguard Worker         goto clean;
179*6236dae4SAndroid Build Coastguard Worker       }
180*6236dae4SAndroid Build Coastguard Worker 
181*6236dae4SAndroid Build Coastguard Worker     }
182*6236dae4SAndroid Build Coastguard Worker     else {
183*6236dae4SAndroid Build Coastguard Worker       result = CURLE_BAD_FUNCTION_ARGUMENT;
184*6236dae4SAndroid Build Coastguard Worker       goto clean;
185*6236dae4SAndroid Build Coastguard Worker     }
186*6236dae4SAndroid Build Coastguard Worker   }
187*6236dae4SAndroid Build Coastguard Worker   else {
188*6236dae4SAndroid Build Coastguard Worker     /* this is ensured to end in a trailing / within ipfs_gateway() */
189*6236dae4SAndroid Build Coastguard Worker     gateway = ipfs_gateway();
190*6236dae4SAndroid Build Coastguard Worker     if(!gateway) {
191*6236dae4SAndroid Build Coastguard Worker       result = CURLE_FILE_COULDNT_READ_FILE;
192*6236dae4SAndroid Build Coastguard Worker       goto clean;
193*6236dae4SAndroid Build Coastguard Worker     }
194*6236dae4SAndroid Build Coastguard Worker 
195*6236dae4SAndroid Build Coastguard Worker     if(curl_url_set(gatewayurl, CURLUPART_URL, gateway, 0)) {
196*6236dae4SAndroid Build Coastguard Worker       result = CURLE_URL_MALFORMAT;
197*6236dae4SAndroid Build Coastguard Worker       goto clean;
198*6236dae4SAndroid Build Coastguard Worker     }
199*6236dae4SAndroid Build Coastguard Worker   }
200*6236dae4SAndroid Build Coastguard Worker 
201*6236dae4SAndroid Build Coastguard Worker   /* check for unsupported gateway parts */
202*6236dae4SAndroid Build Coastguard Worker   if(curl_url_get(gatewayurl, CURLUPART_QUERY, &gwquery, 0)
203*6236dae4SAndroid Build Coastguard Worker                   != CURLUE_NO_QUERY) {
204*6236dae4SAndroid Build Coastguard Worker     result = CURLE_URL_MALFORMAT;
205*6236dae4SAndroid Build Coastguard Worker     goto clean;
206*6236dae4SAndroid Build Coastguard Worker   }
207*6236dae4SAndroid Build Coastguard Worker 
208*6236dae4SAndroid Build Coastguard Worker   /* get gateway parts */
209*6236dae4SAndroid Build Coastguard Worker   if(curl_url_get(gatewayurl, CURLUPART_HOST,
210*6236dae4SAndroid Build Coastguard Worker                   &gwhost, CURLU_URLDECODE)) {
211*6236dae4SAndroid Build Coastguard Worker     goto clean;
212*6236dae4SAndroid Build Coastguard Worker   }
213*6236dae4SAndroid Build Coastguard Worker 
214*6236dae4SAndroid Build Coastguard Worker   if(curl_url_get(gatewayurl, CURLUPART_SCHEME,
215*6236dae4SAndroid Build Coastguard Worker                   &gwscheme, CURLU_URLDECODE)) {
216*6236dae4SAndroid Build Coastguard Worker     goto clean;
217*6236dae4SAndroid Build Coastguard Worker   }
218*6236dae4SAndroid Build Coastguard Worker 
219*6236dae4SAndroid Build Coastguard Worker   curl_url_get(gatewayurl, CURLUPART_PORT, &gwport, CURLU_URLDECODE);
220*6236dae4SAndroid Build Coastguard Worker   curl_url_get(gatewayurl, CURLUPART_PATH, &gwpath, CURLU_URLDECODE);
221*6236dae4SAndroid Build Coastguard Worker 
222*6236dae4SAndroid Build Coastguard Worker   /* get the path from user input */
223*6236dae4SAndroid Build Coastguard Worker   curl_url_get(uh, CURLUPART_PATH, &inputpath, CURLU_URLDECODE);
224*6236dae4SAndroid Build Coastguard Worker   /* inputpath might be NULL or a valid pointer now */
225*6236dae4SAndroid Build Coastguard Worker 
226*6236dae4SAndroid Build Coastguard Worker   /* set gateway parts in input url */
227*6236dae4SAndroid Build Coastguard Worker   if(curl_url_set(uh, CURLUPART_SCHEME, gwscheme, CURLU_URLENCODE) ||
228*6236dae4SAndroid Build Coastguard Worker      curl_url_set(uh, CURLUPART_HOST, gwhost, CURLU_URLENCODE) ||
229*6236dae4SAndroid Build Coastguard Worker      curl_url_set(uh, CURLUPART_PORT, gwport, CURLU_URLENCODE))
230*6236dae4SAndroid Build Coastguard Worker     goto clean;
231*6236dae4SAndroid Build Coastguard Worker 
232*6236dae4SAndroid Build Coastguard Worker   /* if the input path is just a slash, clear it */
233*6236dae4SAndroid Build Coastguard Worker   if(inputpath && (inputpath[0] == '/') && !inputpath[1])
234*6236dae4SAndroid Build Coastguard Worker     *inputpath = '\0';
235*6236dae4SAndroid Build Coastguard Worker 
236*6236dae4SAndroid Build Coastguard Worker   /* ensure the gateway path ends with a trailing slash */
237*6236dae4SAndroid Build Coastguard Worker   ensure_trailing_slash(&gwpath);
238*6236dae4SAndroid Build Coastguard Worker 
239*6236dae4SAndroid Build Coastguard Worker   pathbuffer = aprintf("%s%s/%s%s", gwpath, protocol, cid,
240*6236dae4SAndroid Build Coastguard Worker                        inputpath ? inputpath : "");
241*6236dae4SAndroid Build Coastguard Worker   if(!pathbuffer) {
242*6236dae4SAndroid Build Coastguard Worker     goto clean;
243*6236dae4SAndroid Build Coastguard Worker   }
244*6236dae4SAndroid Build Coastguard Worker 
245*6236dae4SAndroid Build Coastguard Worker   if(curl_url_set(uh, CURLUPART_PATH, pathbuffer, CURLU_URLENCODE)) {
246*6236dae4SAndroid Build Coastguard Worker     goto clean;
247*6236dae4SAndroid Build Coastguard Worker   }
248*6236dae4SAndroid Build Coastguard Worker 
249*6236dae4SAndroid Build Coastguard Worker   /* Free whatever it has now, rewriting is next */
250*6236dae4SAndroid Build Coastguard Worker   Curl_safefree(*url);
251*6236dae4SAndroid Build Coastguard Worker 
252*6236dae4SAndroid Build Coastguard Worker   if(curl_url_get(uh, CURLUPART_URL, &cloneurl, CURLU_URLENCODE)) {
253*6236dae4SAndroid Build Coastguard Worker     goto clean;
254*6236dae4SAndroid Build Coastguard Worker   }
255*6236dae4SAndroid Build Coastguard Worker   /* we need to strdup the URL so that we can call free() on it later */
256*6236dae4SAndroid Build Coastguard Worker   *url = strdup(cloneurl);
257*6236dae4SAndroid Build Coastguard Worker   curl_free(cloneurl);
258*6236dae4SAndroid Build Coastguard Worker   if(!*url)
259*6236dae4SAndroid Build Coastguard Worker     goto clean;
260*6236dae4SAndroid Build Coastguard Worker 
261*6236dae4SAndroid Build Coastguard Worker   result = CURLE_OK;
262*6236dae4SAndroid Build Coastguard Worker 
263*6236dae4SAndroid Build Coastguard Worker clean:
264*6236dae4SAndroid Build Coastguard Worker   free(gateway);
265*6236dae4SAndroid Build Coastguard Worker   curl_free(gwhost);
266*6236dae4SAndroid Build Coastguard Worker   curl_free(gwpath);
267*6236dae4SAndroid Build Coastguard Worker   curl_free(gwquery);
268*6236dae4SAndroid Build Coastguard Worker   curl_free(inputpath);
269*6236dae4SAndroid Build Coastguard Worker   curl_free(gwscheme);
270*6236dae4SAndroid Build Coastguard Worker   curl_free(gwport);
271*6236dae4SAndroid Build Coastguard Worker   curl_free(cid);
272*6236dae4SAndroid Build Coastguard Worker   curl_free(pathbuffer);
273*6236dae4SAndroid Build Coastguard Worker   curl_url_cleanup(gatewayurl);
274*6236dae4SAndroid Build Coastguard Worker   {
275*6236dae4SAndroid Build Coastguard Worker     switch(result) {
276*6236dae4SAndroid Build Coastguard Worker     case CURLE_URL_MALFORMAT:
277*6236dae4SAndroid Build Coastguard Worker       helpf(tool_stderr, "malformed target URL");
278*6236dae4SAndroid Build Coastguard Worker       break;
279*6236dae4SAndroid Build Coastguard Worker     case CURLE_FILE_COULDNT_READ_FILE:
280*6236dae4SAndroid Build Coastguard Worker       helpf(tool_stderr, "IPFS automatic gateway detection failed");
281*6236dae4SAndroid Build Coastguard Worker       break;
282*6236dae4SAndroid Build Coastguard Worker     case CURLE_BAD_FUNCTION_ARGUMENT:
283*6236dae4SAndroid Build Coastguard Worker       helpf(tool_stderr, "--ipfs-gateway was given a malformed URL");
284*6236dae4SAndroid Build Coastguard Worker       break;
285*6236dae4SAndroid Build Coastguard Worker     default:
286*6236dae4SAndroid Build Coastguard Worker       break;
287*6236dae4SAndroid Build Coastguard Worker     }
288*6236dae4SAndroid Build Coastguard Worker   }
289*6236dae4SAndroid Build Coastguard Worker   return result;
290*6236dae4SAndroid Build Coastguard Worker }
291*6236dae4SAndroid Build Coastguard Worker #endif /* !CURL_DISABLE_IPFS */
292