Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
urllib.qc File Reference
#include "urllib.qh"
Include dependency graph for urllib.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

ERASEABLE void url_fclose (entity e)
ERASEABLE string url_fgets (entity e)
ERASEABLE void url_fputs (entity e, string s)
ERASEABLE void url_multi_fopen (string url, int mode, url_ready_func rdy, entity pass)
ERASEABLE void url_multi_ready (entity fh, entity me, float status)
ERASEABLE void url_single_fopen (string url, int mode, url_ready_func rdy, entity pass)
ERASEABLE float url_URI_Get_Callback (int id, float status, string data)

Variables

int autocvar__urllib_nextslot
int url_attempt
string url_content_type
float url_fh
const float URL_FH_CURL = -1
const float URL_FH_STDOUT = -2
entity url_fromid [NUM_URL_ID]
float url_id
int url_mode
float url_rbuf
float url_rbufpos
url_ready_func url_ready
entity url_ready_pass
string url_url
string url_verb
float url_wbuf
float url_wbufpos

Function Documentation

◆ url_fclose()

ERASEABLE void url_fclose ( entity e)

Definition at line 207 of file urllib.qc.

208{
209 int i;
210
211 if (e.url_fh == URL_FH_CURL)
212 {
213 if (e.url_rbuf == -1 || e.url_wbuf != -1) // not(post GET/POST request)
214 if (e.url_rbuf != -1 || e.url_wbuf == -1) // not(pre POST request)
215 error("url_fclose: not closable in current state");
216
217 // closing an URL!
218 if (e.url_wbuf >= 0)
219 {
220 // we are closing the write end (HTTP POST request)
221
222 // get slot for HTTP request
223 for (i = autocvar__urllib_nextslot; i < NUM_URL_ID; ++i)
224 if (url_fromid[i] == NULL) break;
225 if (i >= NUM_URL_ID)
226 {
227 for (i = 0; i < autocvar__urllib_nextslot; ++i)
228 if (url_fromid[i] == NULL) break;
230 {
231 LOG_INFO("url_fclose: too many concurrent requests");
232 e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
233 buf_del(e.url_wbuf);
234 strfree(e.url_url);
235 delete(e);
236 return;
237 }
238 }
239
240 // POST the data
241 if (!crypto_uri_postbuf(e.url_url, i + MIN_URL_ID, e.url_content_type, e.url_verb, e.url_wbuf, 0))
242 {
243 LOG_INFO("url_fclose: failure in crypto_uri_postbuf");
244 e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
245 buf_del(e.url_wbuf);
246 strfree(e.url_url);
247 delete(e);
248 return;
249 }
250
251 // delete write end. File handle is now in unusable
252 // state. Wait for data to come from the server, then
253 // call the callback
254 buf_del(e.url_wbuf);
255 e.url_wbuf = -1;
256 e.url_id = i;
257 url_fromid[i] = e;
258
259 // make sure this slot won't be reused quickly even on map change
260 cvar_set("_urllib_nextslot", ftos((i + 1) % NUM_URL_ID));
261 }
262 else
263 {
264 // we have READ all data, just close
265 e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED);
266 buf_del(e.url_rbuf);
267 strfree(e.url_url);
268 delete(e);
269 }
270 }
271 else if (e.url_fh == URL_FH_STDOUT)
272 {
273 e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED); // closing creates no reading handle
274 delete(e);
275 }
276 else
277 {
278 // file
279 fclose(e.url_fh);
280 e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED); // closing creates no reading handle
281 delete(e);
282 }
283}
#define LOG_INFO(...)
Definition log.qh:65
void cvar_set(string name, string value)
void fclose(float fhandle)
string ftos(float f)
#define NULL
Definition post.qh:14
#define error
Definition pre.qh:6
#define strfree(this)
Definition string.qh:59
int autocvar__urllib_nextslot
Definition urllib.qc:25
const float URL_FH_CURL
Definition urllib.qc:5
entity url_fromid[NUM_URL_ID]
Definition urllib.qc:24
const float URL_FH_STDOUT
Definition urllib.qc:6
const float URL_READY_CLOSED
Definition urllib.qh:15
const float URL_READY_ERROR
Definition urllib.qh:14
#define MIN_URL_ID
Definition urllib.qh:33
#define NUM_URL_ID
Definition urllib.qh:34

References autocvar__urllib_nextslot, cvar_set(), entity(), error, fclose(), ftos(), LOG_INFO, MIN_URL_ID, NULL, NUM_URL_ID, strfree, URL_FH_CURL, URL_FH_STDOUT, url_fromid, URL_READY_CLOSED, and URL_READY_ERROR.

Referenced by AdditionalServerInfo_OnGet(), MX_JLF_(), MX_Messages_(), MX_Nick_(), MX_Say_(), MX_Sync_(), MX_Typing_(), PlayerStats_GameReport_Handler(), PlayerStats_PlayerBasic_Handler(), PlayerStats_PlayerDetail_Handler(), WeaponStats_ready(), and XonoticToS_OnGet().

◆ url_fgets()

ERASEABLE string url_fgets ( entity e)

Definition at line 287 of file urllib.qc.

288{
289 if (e.url_fh == URL_FH_CURL)
290 {
291 if (e.url_rbuf == -1) error("url_fgets: not readable in current state");
292 // curl
293 string s;
294 s = bufstr_get(e.url_rbuf, e.url_rbufpos);
295 e.url_rbufpos += 1;
296 return s;
297 }
298 else if (e.url_fh == URL_FH_STDOUT)
299 {
300 // stdout
301 return string_null;
302 }
303 else
304 {
305 // file
306 return fgets(e.url_fh);
307 }
308}
string fgets(float fhandle)
string string_null
Definition nil.qh:9

References entity(), error, fgets(), string_null, URL_FH_CURL, and URL_FH_STDOUT.

Referenced by AdditionalServerInfo_OnGet(), MX_Messages_(), MX_Sync_(), PlayerStats_GameReport_Handler(), PlayerStats_PlayerBasic_Handler(), PlayerStats_PlayerDetail_Handler(), WeaponStats_ready(), and XonoticToS_OnGet().

◆ url_fputs()

ERASEABLE void url_fputs ( entity e,
string s )

Definition at line 312 of file urllib.qc.

313{
314 if (e.url_fh == URL_FH_CURL)
315 {
316 if (e.url_wbuf == -1) error("url_fputs: not writable in current state");
317 // curl
318 bufstr_set(e.url_wbuf, e.url_wbufpos, s);
319 e.url_wbufpos += 1;
320 }
321 else if (e.url_fh == URL_FH_STDOUT)
322 {
323 // stdout
324 print(s);
325 }
326 else
327 {
328 // file
329 fputs(e.url_fh, s);
330 }
331}
void fputs(float fhandle, string s)
void print(string text,...)

References entity(), error, fputs(), print(), URL_FH_CURL, and URL_FH_STDOUT.

Referenced by MX_JLF_(), MX_Nick_(), MX_Say_(), MX_Typing_(), PlayerStats_GameReport_Handler(), PlayerStats_PlayerBasic_Handler(), PlayerStats_PlayerDetail_Handler(), and WeaponStats_ready().

◆ url_multi_fopen()

ERASEABLE void url_multi_fopen ( string url,
int mode,
url_ready_func rdy,
entity pass )

Definition at line 364 of file urllib.qc.

365{
366 float n;
367 n = tokenize_console(url);
368 if (n <= 0)
369 {
370 LOG_INFO("url_multi_fopen: need at least one URL");
372 return;
373 }
374
375 entity me = new_pure(url_multi);
376 me.url_url = strzone(url);
377 me.url_attempt = 0;
378 me.url_mode = mode;
379 me.url_ready = rdy;
380 me.url_ready_pass = pass;
382}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define tokenize_console
#define pass(name, colormin, colormax)
string strzone(string s)
string argv(float n)
#define new_pure(class)
purely logical entities (not linked to the area grid)
Definition oo.qh:67
ERASEABLE void url_multi_ready(entity fh, entity me, float status)
Definition urllib.qc:335
ERASEABLE void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
Definition urllib.qc:87

References argv(), entity(), LOG_INFO, new_pure, NULL, pass, strzone(), tokenize_console, url_multi_ready(), URL_READY_ERROR, and url_single_fopen().

Referenced by PlayerStats_GameReport(), and WeaponStats_Shutdown().

◆ url_multi_ready()

ERASEABLE void url_multi_ready ( entity fh,
entity me,
float status )

Definition at line 335 of file urllib.qc.

336{
337 float n;
338 if (status == URL_READY_ERROR || status < 0)
339 {
340 if (status == -422) // Unprocessable Entity
341 {
342 LOG_INFO("uri_multi_ready: got HTTP error 422, data is in unusable format - not continuing");
343 me.url_ready(fh, me.url_ready_pass, status);
344 strfree(me.url_url);
345 delete(me);
346 return;
347 }
348 me.url_attempt += 1;
349 n = tokenize_console(me.url_url);
350 if (n <= me.url_attempt)
351 {
352 me.url_ready(fh, me.url_ready_pass, status);
353 strfree(me.url_url);
354 delete(me);
355 return;
356 }
357 url_single_fopen(argv(me.url_attempt), me.url_mode, url_multi_ready, me);
358 return;
359 }
360 me.url_ready(fh, me.url_ready_pass, status);
361}

References argv(), entity(), LOG_INFO, strfree, tokenize_console, url_multi_ready(), URL_READY_ERROR, and url_single_fopen().

Referenced by url_multi_fopen(), and url_multi_ready().

◆ url_single_fopen()

ERASEABLE void url_single_fopen ( string url,
int mode,
url_ready_func rdy,
entity pass )

Definition at line 87 of file urllib.qc.

88{
89 entity e;
90 int i;
91 if (strstrofs(url, "://", 0) >= 0)
92 {
93 switch (mode)
94 {
95 case FILE_WRITE:
96 case FILE_APPEND:
97 // collect data to a stringbuffer for a POST request
98 // attempts to close will result in a reading handle
99
100 // create a writing end that does nothing yet
101 e = new_pure(url_single_fopen_file);
102 e.url_url = strzone(url);
103 e.url_content_type = "text/plain";
104 e.url_verb = "";
105 e.url_fh = URL_FH_CURL;
106 e.url_wbuf = buf_create();
107 if (e.url_wbuf < 0)
108 {
109 LOG_INFO("url_single_fopen: out of memory in buf_create");
110 rdy(e, pass, URL_READY_ERROR);
111 strfree(e.url_url);
112 delete(e);
113 return;
114 }
115 e.url_wbufpos = 0;
116 e.url_rbuf = -1;
117 e.url_ready = rdy;
118 e.url_ready_pass = pass;
119 rdy(e, pass, URL_READY_CANWRITE);
120 break;
121
122 case FILE_READ:
123 // read data only
124
125 // get slot for HTTP request
126 for (i = autocvar__urllib_nextslot; i < NUM_URL_ID; ++i)
127 if (url_fromid[i] == NULL) break;
128 if (i >= NUM_URL_ID)
129 {
130 for (i = 0; i < autocvar__urllib_nextslot; ++i)
131 if (url_fromid[i] == NULL) break;
133 {
134 LOG_INFO("url_single_fopen: too many concurrent requests");
136 return;
137 }
138 }
139
140 // GET the data
141 if (!crypto_uri_postbuf(url, i + MIN_URL_ID, string_null, string_null, -1, 0))
142 {
143 LOG_INFO("url_single_fopen: failure in crypto_uri_postbuf");
145 return;
146 }
147
148 // Make a dummy handle object (no buffers at
149 // all). Wait for data to come from the
150 // server, then call the callback
151 e = new_pure(url_single_fopen_file);
152 e.url_url = strzone(url);
153 e.url_fh = URL_FH_CURL;
154 e.url_rbuf = -1;
155 e.url_wbuf = -1;
156 e.url_ready = rdy;
157 e.url_ready_pass = pass;
158 e.url_id = i;
159 url_fromid[i] = e;
160
161 // make sure this slot won't be reused quickly even on map change
162 cvar_set("_urllib_nextslot", ftos((i + 1) % NUM_URL_ID));
163 break;
164 }
165 }
166 else if (url == "-")
167 {
168 switch (mode)
169 {
170 case FILE_WRITE:
171 case FILE_APPEND:
172 e = new_pure(url_single_fopen_stdout);
173 e.url_fh = URL_FH_STDOUT;
174 e.url_ready = rdy;
175 e.url_ready_pass = pass;
176 rdy(e, pass, URL_READY_CANWRITE);
177 break;
178 case FILE_READ:
179 LOG_INFO("url_single_fopen: cannot open '-' for reading");
181 break;
182 }
183 }
184 else
185 {
186 float fh;
187 fh = fopen(url, mode);
188 if (fh < 0)
189 {
191 return;
192 }
193 else
194 {
195 e = new_pure(url_single_fopen_file);
196 e.url_fh = fh;
197 e.url_ready = rdy;
198 e.url_ready_pass = pass;
199 if (mode == FILE_READ) rdy(e, pass, URL_READY_CANREAD);
200 else rdy(e, pass, URL_READY_CANWRITE);
201 }
202 }
203}
const float FILE_READ
const float FILE_WRITE
const float FILE_APPEND
#define strstrofs
#define buf_create
float fopen(string filename, float mode)
const float URL_READY_CANREAD
Definition urllib.qh:17
const float URL_READY_CANWRITE
Definition urllib.qh:16

References autocvar__urllib_nextslot, buf_create, cvar_set(), entity(), FILE_APPEND, FILE_READ, FILE_WRITE, fopen(), ftos(), LOG_INFO, MIN_URL_ID, new_pure, NULL, NUM_URL_ID, pass, strfree, string_null, strstrofs, strzone(), URL_FH_CURL, URL_FH_STDOUT, url_fromid, URL_READY_CANREAD, URL_READY_CANWRITE, and URL_READY_ERROR.

Referenced by MX_Forget(), MX_Join(), MX_Leave(), MX_Messages(), MX_Nick(), MX_Say(), MX_Sync(), MX_Typing(), PlayerStats_PlayerBasic(), PlayerStats_PlayerDetail(), url_multi_fopen(), url_multi_ready(), XonoticServerToSTab_loadToS(), and XonoticToSDialog_loadXonoticToS().

◆ url_URI_Get_Callback()

ERASEABLE float url_URI_Get_Callback ( int id,
float status,
string data )

Definition at line 28 of file urllib.qc.

29{
30 if (id < MIN_URL_ID) return 0;
31 id -= MIN_URL_ID;
32 if (id >= NUM_URL_ID) return 0;
33 entity e;
34 e = url_fromid[id];
35 if (!e) return 0;
36 if (e.url_rbuf >= 0 || e.url_wbuf >= 0)
37 {
38 LOG_INFOF("WARNING: handle %d (%s) has already received data?!?", id + NUM_URL_ID, e.url_url);
39 return 0;
40 }
41
42 // whatever happens, we will remove the URL from the list of IDs
43 url_fromid[id] = NULL;
44
45 // if we get here, we MUST have both buffers cleared
46 if (e.url_rbuf != -1 || e.url_wbuf != -1 || e.url_fh != URL_FH_CURL) error("url_URI_Get_Callback: not a request waiting for data");
47
48 if (status == 0)
49 {
50 // WE GOT DATA!
51 float n, i;
52 n = tokenizebyseparator(data, "\n");
53 e.url_rbuf = buf_create();
54 if (e.url_rbuf < 0)
55 {
56 LOG_INFO("url_URI_Get_Callback: out of memory in buf_create");
57 e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
58 strfree(e.url_url);
59 delete(e);
60 return 1;
61 }
62 e.url_rbufpos = 0;
63 if (e.url_rbuf < 0)
64 {
65 LOG_INFO("url_URI_Get_Callback: out of memory in buf_create");
66 e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
67 strfree(e.url_url);
68 delete(e);
69 return 1;
70 }
71 for (i = 0; i < n; ++i)
72 bufstr_set(e.url_rbuf, i, argv(i));
73 e.url_ready(e, e.url_ready_pass, URL_READY_CANREAD);
74 return 1;
75 }
76 else
77 {
78 // an ERROR
79 e.url_ready(e, e.url_ready_pass, -fabs(status));
80 strfree(e.url_url);
81 delete(e);
82 return 1;
83 }
84}
#define tokenizebyseparator
#define LOG_INFOF(...)
Definition log.qh:66
float fabs(float f)

References argv(), buf_create, entity(), error, fabs(), LOG_INFO, LOG_INFOF, MIN_URL_ID, NULL, NUM_URL_ID, strfree, tokenizebyseparator, URL_FH_CURL, url_fromid, URL_READY_CANREAD, and URL_READY_ERROR.

Referenced by URI_Get_Callback(), and URI_Get_Callback().

Variable Documentation

◆ autocvar__urllib_nextslot

int autocvar__urllib_nextslot

Definition at line 25 of file urllib.qc.

Referenced by url_fclose(), and url_single_fopen().

◆ url_attempt

int url_attempt

Definition at line 21 of file urllib.qc.

◆ url_content_type

string url_content_type

Definition at line 10 of file urllib.qc.

◆ url_fh

float url_fh

Definition at line 4 of file urllib.qc.

◆ URL_FH_CURL

const float URL_FH_CURL = -1

Definition at line 5 of file urllib.qc.

Referenced by url_fclose(), url_fgets(), url_fputs(), url_single_fopen(), and url_URI_Get_Callback().

◆ URL_FH_STDOUT

const float URL_FH_STDOUT = -2

Definition at line 6 of file urllib.qc.

Referenced by url_fclose(), url_fgets(), url_fputs(), and url_single_fopen().

◆ url_fromid

entity url_fromid[NUM_URL_ID]

Definition at line 24 of file urllib.qc.

Referenced by url_fclose(), url_single_fopen(), and url_URI_Get_Callback().

◆ url_id

float url_id

Definition at line 16 of file urllib.qc.

◆ url_mode

int url_mode

Definition at line 22 of file urllib.qc.

◆ url_rbuf

float url_rbuf

Definition at line 14 of file urllib.qc.

◆ url_rbufpos

float url_rbufpos

Definition at line 15 of file urllib.qc.

◆ url_ready

url_ready_func url_ready

Definition at line 17 of file urllib.qc.

◆ url_ready_pass

entity url_ready_pass

Definition at line 18 of file urllib.qc.

◆ url_url

string url_url

Definition at line 9 of file urllib.qc.

◆ url_verb

string url_verb

Definition at line 11 of file urllib.qc.

◆ url_wbuf

float url_wbuf

Definition at line 12 of file urllib.qc.

◆ url_wbufpos

float url_wbufpos

Definition at line 13 of file urllib.qc.