Mercurial > sci
annotate libsci/apic.c @ 35:084dee2bef50
man: updates
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 04 Aug 2022 18:01:29 +0200 |
parents | 1d0ddf9e6efd |
children | b474f0985e39 |
rev | line source |
---|---|
33
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
1 /* |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
2 * apic.c -- synchronous HTTP request |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
3 * |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
4 * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr> |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
5 * |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
9 * |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
17 */ |
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
18 |
19 | 19 #include <assert.h> |
20 #include <errno.h> | |
21 #include <stdarg.h> | |
22 #include <stdio.h> | |
23 #include <string.h> | |
24 | |
25 #include <curl/curl.h> | |
26 | |
27 #include "apic.h" | |
28 #include "util.h" | |
29 | |
30 struct curlpack { | |
31 CURL *curl; | |
32 CURLcode code; | |
33 struct curl_slist *headers; | |
34 }; | |
35 | |
20 | 36 struct apiconf apiconf = { |
37 .baseurl = "http://127.0.0.1" | |
38 }; | |
39 | |
19 | 40 static size_t |
41 writer(char *in, size_t n, size_t w, FILE *fp) | |
42 { | |
43 if (fwrite(in, n, w, fp) != w) | |
44 return 0; | |
45 | |
46 return w; | |
47 } | |
48 | |
49 static inline char * | |
50 create_url(const char *fmt, va_list args) | |
51 { | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
52 static _Thread_local char ret[1024]; |
20 | 53 char page[128]; |
19 | 54 va_list ap; |
55 | |
56 ret[0] = 0; | |
57 va_copy(ap, args); | |
20 | 58 vsnprintf(page, sizeof (page), fmt, ap); |
19 | 59 va_end(ap); |
60 | |
20 | 61 snprintf(ret, sizeof (ret), "%s/%s", apiconf.baseurl, page); |
62 | |
19 | 63 return ret; |
64 } | |
65 | |
66 static inline FILE * | |
67 create_file(char **buf, size_t *bufsz) | |
68 { | |
69 FILE *fp; | |
70 | |
71 *buf = NULL; | |
72 *bufsz = 0; | |
73 | |
74 if (!(fp = open_memstream(buf, bufsz))) | |
75 util_die("open_memstream: %s\n", strerror(errno)); | |
76 | |
77 return fp; | |
78 } | |
79 | |
80 static struct curlpack | |
81 create_curl(FILE *fp, const char *body, const char *url) | |
82 { | |
83 struct curlpack pack = {0}; | |
84 | |
85 pack.headers = curl_slist_append(pack.headers, "Content-Type: application/json"); | |
86 pack.curl = curl_easy_init(); | |
87 curl_easy_setopt(pack.curl, CURLOPT_HTTPHEADER, pack.headers); | |
88 curl_easy_setopt(pack.curl, CURLOPT_URL, url); | |
89 curl_easy_setopt(pack.curl, CURLOPT_FOLLOWLOCATION, 1L); | |
90 curl_easy_setopt(pack.curl, CURLOPT_TIMEOUT, 3L); | |
91 curl_easy_setopt(pack.curl, CURLOPT_WRITEFUNCTION, writer); | |
92 curl_easy_setopt(pack.curl, CURLOPT_WRITEDATA, fp); | |
93 curl_easy_setopt(pack.curl, CURLOPT_NOSIGNAL, 1L); | |
94 | |
95 /* Assume POST request if there is a body. */ | |
96 if (body) { | |
97 curl_easy_setopt(pack.curl, CURLOPT_POSTFIELDS, body); | |
98 curl_easy_setopt(pack.curl, CURLOPT_POSTFIELDSIZE, strlen(body)); | |
99 } | |
100 | |
101 pack.code = curl_easy_perform(pack.curl); | |
102 | |
103 return pack; | |
104 } | |
105 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
106 static json_t * |
20 | 107 perform(struct apic *req, const char *body, const char *fmt, va_list ap) |
19 | 108 { |
109 FILE *fp; | |
110 char *response, *url; | |
111 size_t responsesz; | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
112 json_t *doc = NULL; |
19 | 113 json_error_t error; |
114 struct curlpack curl; | |
115 | |
116 memset(req, 0, sizeof (*req)); | |
117 | |
118 url = create_url(fmt, ap); | |
119 fp = create_file(&response, &responsesz); | |
120 curl = create_curl(fp, body, url); | |
121 | |
122 /* Perform that request now. */ | |
123 fclose(fp); | |
124 | |
125 if (curl.code != CURLE_OK) | |
126 snprintf(req->error, sizeof (req->error), "%s", curl_easy_strerror(curl.code)); | |
127 else { | |
128 curl_easy_getinfo(curl.curl, CURLINFO_RESPONSE_CODE, &req->status); | |
129 | |
130 if (req->status != 200) | |
131 snprintf(req->error, sizeof (req->error), "HTTP returned %ld", req->status); | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
132 if (response[0] && !(doc = json_loads(response, 0, &error))) |
19 | 133 snprintf(req->error, sizeof (req->error), "JSON parse error: %s", error.text); |
134 } | |
135 | |
136 curl_easy_cleanup(curl.curl); | |
137 curl_slist_free_all(curl.headers); | |
138 | |
139 free(response); | |
140 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
141 return doc; |
19 | 142 } |
143 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
144 static json_t * |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
145 get(struct apic *req, const char *fmt, ...) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
146 { |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
147 va_list ap; |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
148 json_t *ret; |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
149 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
150 va_start(ap, fmt); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
151 ret = perform(req, NULL, fmt, ap); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
152 va_end(ap); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
153 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
154 if (!ret || (!json_is_object(ret) && !json_is_array(ret))) |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
155 snprintf(req->error, sizeof (req->error), "invalid JSON document received"); |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
156 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
157 return ret; |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
158 } |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
159 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
160 static int |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
161 create(struct apic *req, json_t *doc, const char *fmt, ...) |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
162 { |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
163 va_list ap; |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
164 json_t *ret; |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
165 char *body; |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
166 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
167 memset(req, 0, sizeof (*req)); |
33
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
168 body = util_json_dump(doc); |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
169 |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
170 va_start(ap, fmt); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
171 ret = perform(req, body, fmt, ap); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
172 va_end(ap); |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
173 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
174 /* TODO: update id. */ |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
175 (void)ret; |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
176 |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
177 free(body); |
33
1d0ddf9e6efd
misc: general documentation
David Demelier <markand@malikania.fr>
parents:
27
diff
changeset
|
178 json_decref(ret); |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
179 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
180 return 0; |
22
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
181 } |
dd078aea5d02
misc: use project/worker name as primary key
David Demelier <markand@malikania.fr>
parents:
20
diff
changeset
|
182 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
183 json_t * |
20 | 184 apic_get(struct apic *req, const char *fmt, ...) |
19 | 185 { |
186 assert(req); | |
187 assert(fmt); | |
188 | |
189 va_list ap; | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
190 json_t *ret; |
19 | 191 |
192 va_start(ap, fmt); | |
193 ret = perform(req, NULL, fmt, ap); | |
194 va_end(ap); | |
195 | |
196 return ret; | |
197 } | |
198 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
199 json_t * |
20 | 200 apic_post(struct apic *req, const json_t *doc, const char *fmt, ...) |
19 | 201 { |
202 assert(req); | |
203 assert(fmt); | |
204 | |
205 va_list ap; | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
206 json_t *ret; |
19 | 207 char *body; |
208 | |
209 if (!(body = json_dumps(doc, JSON_COMPACT))) | |
210 util_die("%s", strerror(ENOMEM)); | |
211 | |
212 va_start(ap, fmt); | |
213 ret = perform(req, body, fmt, ap); | |
214 va_end(ap); | |
215 | |
216 free(body); | |
217 | |
218 return ret; | |
219 } | |
20 | 220 |
221 int | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
222 apic_job_add(struct apic *req, json_t *job) |
20 | 223 { |
224 assert(req); | |
225 assert(job); | |
226 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
227 return create(req, job, "api/v1/jobs"); |
20 | 228 } |
229 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
230 json_t * |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
231 apic_job_todo(struct apic *req, const char *worker_name) |
20 | 232 { |
233 assert(req); | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
234 assert(worker_name); |
20 | 235 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
236 return get(req, "api/v1/todo/%s", worker_name); |
20 | 237 } |
238 | |
239 int | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
240 apic_jobresult_add(struct apic *req, json_t *res) |
20 | 241 { |
242 assert(req); | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
243 assert(res); |
20 | 244 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
245 return create(req, res, "api/v1/jobresults"); |
20 | 246 } |
247 | |
248 int | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
249 apic_project_save(struct apic *req, json_t *p) |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
250 { |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
251 assert(req); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
252 assert(p); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
253 |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
254 return create(req, p, "api/v1/projects"); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
255 } |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
256 |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
257 json_t * |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
258 apic_project_list(struct apic *req) |
20 | 259 { |
260 assert(req); | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
261 |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
262 return get(req, "api/v1/projects"); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
263 } |
20 | 264 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
265 json_t * |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
266 apic_project_find(struct apic *req, const char *name) |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
267 { |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
268 assert(req); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
269 assert(name); |
20 | 270 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
271 return get(req, "api/v1/projects/%s", name); |
20 | 272 } |
273 | |
274 int | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
275 apic_worker_save(struct apic *req, json_t *wk) |
20 | 276 { |
277 assert(req); | |
278 assert(wk); | |
279 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
280 return create(req, wk, "api/v1/workers"); |
20 | 281 } |
282 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
283 json_t * |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
284 apic_worker_list(struct apic *req) |
20 | 285 { |
286 assert(req); | |
287 | |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
288 return get(req, "api/v1/workers"); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
289 } |
20 | 290 |
27
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
291 json_t * |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
292 apic_worker_find(struct apic *req, const char *name) |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
293 { |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
294 assert(req); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
295 assert(name); |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
296 |
dae2de19ca5d
misc: switch to JSON everywhere
David Demelier <markand@malikania.fr>
parents:
24
diff
changeset
|
297 return get(req, "api/v1/workers/%s", name); |
20 | 298 } |