Tip of the day: With the UnrealIRCd administration panel you can add and remove server bans and do other server management from your browser. |
Dev:URL API
You can do web requests from a module, for example a HTTPS callout to receive some JSON.
Below we explain how to do this. Behind the scenes UnrealIRCd keeps things safe, even if the server is REHASHed between starting the request and receiving the response (and your module is reloaded) things will still work properly and you will still receive the response.
Registering your callback
In your MOD_INIT() use RegisterApiCallbackWebResponse() to register your response handler:
/* Forward declaration */ void my_download_complete(OutgoingWebRequest *request, OutgoingWebResponse *response); MOD_INIT() { [..] RegisterApiCallbackWebResponse(modinfo->handle, "my_download_complete", my_download_complete); return MOD_SUCCESS; }
Doing the web request
Create an OutgoingWebRequest struct and then fill in members. You must set ->apicallback to the name of the api callback that you registered in MOD_INIT above.
Example:
OutgoingWebRequest *w = safe_alloc(sizeof(OutgoingWebRequest)); safe_strdup(w->url, cfg.url); w->http_method = HTTP_METHOD_GET; safe_strdup(w->apicallback, "cbl_download_complete"); url_start_async(w);
You can also set more fields before you call url_start_async
, for example setting w->callback_data
if you need to keep track of different requests.
For all fields, see OutgoingWebRequest in include/struct.h, viewable online here
Receiving the web response
Here is where your my_download_complete comes into play. In this example we expect to receive a JSON response, which we try to parse.
See also docs for OutgoingWebRequest and OutgoingWebResponse to see all struct members of request and response.
void my_download_complete(OutgoingWebRequest *request, OutgoingWebResponse *response) { json_t *result; json_error_t jerr; if (response->errorbuf || !response->memory) { unreal_log(ULOG_INFO, "mymod", "MYMOD_BAD_RESPONSE", NULL, "Error while trying to check $url: $error", log_data_string("url", request->url), log_data_string("error", response->errorbuf ? response->errorbuf : "No data (body) returned")); return; } // result->memory contains all the data of the web response, in our case // we assume it is a JSON response, so we are going to parse it. // If you were expecting BINARY data then you can still use result->memory // but then have a look at the length in result->memory_len. result = json_loads(response->memory, JSON_REJECT_DUPLICATES, &jerr); if (!result) { unreal_log(ULOG_INFO, "mymod", "MYMOD_BAD_RESPONSE", NULL, "Error while trying to check $url: JSON parse error", log_data_string("url", request->url)); return; } // Now do something useful with the json in 'result'. For how to work // with json objects, see the Jansson API documentation at // https://jansson.readthedocs.io/en/latest/ e.g. json_object_get(). // There are also UnrealIRCd specific functions (to make things easier) // such as json_object_get_string(), json_object_get_integer(), // json_object_get_boolean(). // Finally, free 'result' and return json_decref(result); }