static int w_async_rest_get(struct sip_msg *msg, async_resume_module **resume_f, void **resume_param, char *gp_url, char *body_pv, char *ctype_pv, char *code_pv) { rest_async_param *param; str url; int read_fd; if (fixup_get_svalue(msg, (gparam_p)gp_url, &url) != 0) { LM_ERR("Invalid HTTP URL pseudo variable!\n"); return -1; } LM_DBG("async rest get %.*s %p %p %p\n", url.len, url.s, body_pv, ctype_pv, code_pv); param = pkg_malloc(sizeof *param); if (!param) { LM_ERR("no more shm\n"); return -1; } memset(param, '\0', sizeof *param); read_fd = start_async_http_req(msg, REST_CLIENT_GET, url.s, NULL, NULL, ¶m->handle, ¶m->body, ctype_pv ? ¶m->ctype : NULL); /* error occurred; no transfer done */ if (read_fd == ASYNC_NO_IO) { *resume_param = NULL; *resume_f = NULL; /* keep default async status of NO_IO */ return -1; /* no need for async - transfer already completed! */ } else if (read_fd == ASYNC_SYNC) { set_output_pv_params(msg, ¶m->body, (pv_spec_p)body_pv, ¶m->ctype, (pv_spec_p)ctype_pv, param->handle, (pv_spec_p)code_pv); pkg_free(param->body.s); if (ctype_pv && param->ctype.s) pkg_free(param->ctype.s); curl_easy_cleanup(param->handle); pkg_free(param); return ASYNC_SYNC; } *resume_f = resume_async_http_req; param->method = REST_CLIENT_GET; param->body_pv = (pv_spec_p)body_pv; param->ctype_pv = (pv_spec_p)ctype_pv; param->code_pv = (pv_spec_p)code_pv; *resume_param = param; /* async started with success */ async_status = read_fd; return 1; }
int async_rest_method(enum rest_client_method method, struct sip_msg *msg, char *url, str *body, str *ctype, async_ctx *ctx, pv_spec_p body_pv, pv_spec_p ctype_pv, pv_spec_p code_pv) { rest_async_param *param; pv_value_t val; long http_rc; int read_fd, rc; param = pkg_malloc(sizeof *param); if (!param) { LM_ERR("no more shm\n"); return RCL_INTERNAL_ERR; } memset(param, '\0', sizeof *param); rc = start_async_http_req(msg, method, url, body, ctype, param, ¶m->body, ctype_pv ? ¶m->ctype : NULL, &read_fd); /* error occurred; no transfer done */ if (read_fd == ASYNC_NO_IO) { ctx->resume_param = NULL; ctx->resume_f = NULL; /* keep default async status of NO_IO */ pkg_free(param); return rc; /* no need for async - transfer already completed! */ } else if (read_fd == ASYNC_SYNC) { if (code_pv) { curl_easy_getinfo(param->handle, CURLINFO_RESPONSE_CODE, &http_rc); LM_DBG("HTTP response code: %ld\n", http_rc); val.flags = PV_VAL_INT|PV_TYPE_INT; val.ri = (int)http_rc; if (pv_set_value(msg, (pv_spec_p)code_pv, 0, &val) != 0) { LM_ERR("failed to set output code pv\n"); return RCL_INTERNAL_ERR; } } val.flags = PV_VAL_STR; val.rs = param->body; if (pv_set_value(msg, (pv_spec_p)body_pv, 0, &val) != 0) { LM_ERR("failed to set output body pv\n"); return RCL_INTERNAL_ERR; } if (ctype_pv) { val.rs = param->ctype; if (pv_set_value(msg, (pv_spec_p)ctype_pv, 0, &val) != 0) { LM_ERR("failed to set output ctype pv\n"); return RCL_INTERNAL_ERR; } } pkg_free(param->body.s); if (ctype_pv && param->ctype.s) pkg_free(param->ctype.s); curl_easy_cleanup(param->handle); pkg_free(param); async_status = ASYNC_SYNC; return rc; } ctx->resume_f = resume_async_http_req; param->method = method; param->body_pv = (pv_spec_p)body_pv; param->ctype_pv = (pv_spec_p)ctype_pv; param->code_pv = (pv_spec_p)code_pv; ctx->resume_param = param; /* async started with success */ async_status = read_fd; return 1; }