.url_ready_func url_ready;
.entity url_ready_pass;
+// for multi handles
+.float url_attempt;
+.float url_mode;
+
entity url_fromid[NUM_URL_ID];
float autocvar__urllib_nextslot;
return 0;
if(e.url_rbuf >= 0 || e.url_wbuf >= 0)
{
- print(sprintf("WARNING: handle %d (%s) has already received data?!?\n", id + NUM_URL_ID, e.url_url));
+ printf("WARNING: handle %d (%s) has already received data?!?\n", id + NUM_URL_ID, e.url_url);
return 0;
}
}
}
-void url_fopen(string url, float mode, url_ready_func rdy, entity pass)
+void url_single_fopen(string url, float mode, url_ready_func rdy, entity pass)
{
entity e;
float i;
// create a writing end that does nothing yet
e = spawn();
- e.classname = "url_fopen_file";
+ e.classname = "url_single_fopen_file";
e.url_url = strzone(url);
e.url_fh = URL_FH_CURL;
e.url_wbuf = buf_create();
if(e.url_wbuf < 0)
{
- print("url_fopen: out of memory in buf_create\n");
+ print("url_single_fopen: out of memory in buf_create\n");
rdy(e, pass, URL_READY_ERROR);
strunzone(e.url_url);
remove(e);
}
e.url_wbufpos = 0;
e.url_rbuf = -1;
+ e.url_ready = rdy;
+ e.url_ready_pass = pass;
rdy(e, pass, URL_READY_CANWRITE);
break;
break;
if(i >= autocvar__urllib_nextslot)
{
- print("url_fopen: too many concurrent requests\n");
+ print("url_single_fopen: too many concurrent requests\n");
rdy(world, pass, URL_READY_ERROR);
return;
}
// GET the data
if(!crypto_uri_postbuf(url, i + MIN_URL_ID, string_null, string_null, -1, 0))
{
- print("url_fopen: failure in crypto_uri_postbuf\n");
+ print("url_single_fopen: failure in crypto_uri_postbuf\n");
rdy(world, pass, URL_READY_ERROR);
return;
}
// all). Wait for data to come from the
// server, then call the callback
e = spawn();
- e.classname = "url_fopen_file";
+ e.classname = "url_single_fopen_file";
e.url_url = strzone(url);
e.url_fh = URL_FH_CURL;
e.url_rbuf = -1;
case FILE_WRITE:
case FILE_APPEND:
e = spawn();
- e.classname = "url_fopen_stdout";
+ e.classname = "url_single_fopen_stdout";
e.url_fh = URL_FH_STDOUT;
+ e.url_ready = rdy;
+ e.url_ready_pass = pass;
rdy(e, pass, URL_READY_CANWRITE);
break;
case FILE_READ:
- print("url_fopen: cannot open '-' for reading\n");
+ print("url_single_fopen: cannot open '-' for reading\n");
rdy(world, pass, URL_READY_ERROR);
break;
}
else
{
e = spawn();
- e.classname = "url_fopen_file";
+ e.classname = "url_single_fopen_file";
e.url_fh = fh;
+ e.url_ready = rdy;
+ e.url_ready_pass = pass;
if(mode == FILE_READ)
rdy(e, pass, URL_READY_CANREAD);
else
}
// close a file
-void url_fclose(entity e, url_ready_func rdy, entity pass)
+void url_fclose(entity e)
{
float i;
if(i >= autocvar__urllib_nextslot)
{
print("url_fclose: too many concurrent requests\n");
- rdy(e, pass, URL_READY_ERROR);
+ e.url_ready(e,e.url_ready_pass, URL_READY_ERROR);
buf_del(e.url_wbuf);
strunzone(e.url_url);
remove(e);
if(!crypto_uri_postbuf(e.url_url, i + MIN_URL_ID, "text/plain", "", e.url_wbuf, 0))
{
print("url_fclose: failure in crypto_uri_postbuf\n");
- rdy(e, pass, URL_READY_ERROR);
+ e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
buf_del(e.url_wbuf);
strunzone(e.url_url);
remove(e);
// call the callback
buf_del(e.url_wbuf);
e.url_wbuf = -1;
- e.url_ready = rdy;
- e.url_ready_pass = pass;
e.url_id = i;
url_fromid[i] = e;
else
{
// we have READ all data, just close
- rdy(e, pass, URL_READY_CLOSED);
+ e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED);
buf_del(e.url_rbuf);
strunzone(e.url_url);
remove(e);
}
else if(e.url_fh == URL_FH_STDOUT)
{
- rdy(e, pass, URL_READY_CLOSED); // closing creates no reading handle
+ e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED); // closing creates no reading handle
remove(e);
}
else
{
// file
fclose(e.url_fh);
- rdy(e, pass, URL_READY_CLOSED); // closing creates no reading handle
+ e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED); // closing creates no reading handle
remove(e);
}
}
void url_multi_ready(entity fh, entity me, float status)
{
float n;
- if(status == URL_READY_ERROR)
+ if(status == URL_READY_ERROR || status < 0)
{
- me.cnt += 1;
+ if(status == -422) // Unprocessable Entity
+ {
+ print("uri_multi_ready: got HTTP error 422, data is in unusable format - not continuing\n");
+ me.url_ready(fh, me.url_ready_pass, status);
+ strunzone(me.url_url);
+ remove(me);
+ return;
+ }
+ me.url_attempt += 1;
n = tokenize_console(me.url_url);
- if(n <= me.cnt)
+ if(n <= me.url_attempt)
{
me.url_ready(fh, me.url_ready_pass, status);
strunzone(me.url_url);
remove(me);
return;
}
- url_fopen(argv(me.cnt), me.lip, url_multi_ready, me);
+ url_single_fopen(argv(me.url_attempt), me.url_mode, url_multi_ready, me);
return;
}
me.url_ready(fh, me.url_ready_pass, status);
me = spawn();
me.classname = "url_multi";
me.url_url = strzone(url);
- me.cnt = 0;
- me.lip = mode;
+ me.url_attempt = 0;
+ me.url_mode = mode;
me.url_ready = rdy;
me.url_ready_pass = pass;
- url_fopen(argv(0), mode, url_multi_ready, me);
+ url_single_fopen(argv(0), mode, url_multi_ready, me);
}