Explorar el Código

http_client: new function http_client_get()

- do explicit GET request with headers (and body)
- exported KSR.http_client.get_hdrs()
Daniel-Constantin Mierla hace 4 años
padre
commit
b6a1088767

+ 27 - 12
src/modules/http_client/functions.c

@@ -111,11 +111,11 @@ size_t write_function(void *ptr, size_t size, size_t nmemb, void *stream_ptr)
 
 
 /*! Send query to server, optionally post data.
 /*! Send query to server, optionally post data.
  */
  */
-static int curL_query_url(struct sip_msg *_m, const char *_url, str *_dst,
-		const curl_query_t *const params)
+static int curL_request_url(struct sip_msg *_m, const char *_met,
+		const char *_url, str *_dst, const curl_query_t *const params)
 {
 {
 	CURL *curl = NULL;
 	CURL *curl = NULL;
-	;
+
 	CURLcode res;
 	CURLcode res;
 	char *at = NULL;
 	char *at = NULL;
 	curl_res_stream_t stream;
 	curl_res_stream_t stream;
@@ -158,10 +158,15 @@ static int curL_query_url(struct sip_msg *_m, const char *_url, str *_dst,
 	res = curl_easy_setopt(
 	res = curl_easy_setopt(
 			curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
 			curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
 
 
+	if(_met != NULL) {
+		/* Enforce method (GET, PUT, ...) */
+		res |= curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, _met);
+	}
 	if(params->post) {
 	if(params->post) {
-		/* Now specify we want to POST data */
-		res |= curl_easy_setopt(curl, CURLOPT_POST, 1L);
-
+		if(_met == NULL) {
+			/* Now specify we want to POST data */
+			res |= curl_easy_setopt(curl, CURLOPT_POST, 1L);
+		}
 		if(params->contenttype) {
 		if(params->contenttype) {
 			char ctype[256];
 			char ctype[256];
 
 
@@ -593,7 +598,7 @@ int curl_con_query_url_f(struct sip_msg *_m, const str *connection,
 		LM_DBG("**** Curl HTTP_proxy not set \n");
 		LM_DBG("**** Curl HTTP_proxy not set \n");
 	}
 	}
 
 
-	res = curL_query_url(_m, urlbuf, result, &query_params);
+	res = curL_request_url(_m, NULL, urlbuf, result, &query_params);
 
 
 	if(res > 1000 && conn->failover.s) {
 	if(res > 1000 && conn->failover.s) {
 		int counter = failover + 1;
 		int counter = failover + 1;
@@ -630,12 +635,12 @@ int curl_con_query_url(struct sip_msg *_m, const str *connection,
 }
 }
 
 
 /*!
 /*!
- * Performs http_query and saves possible result (first body line of reply)
+ * Performs http request and saves possible result (first body line of reply)
  * to pvar.
  * to pvar.
  * This is the same http_query as used to be in the utils module.
  * This is the same http_query as used to be in the utils module.
  */
  */
-int http_client_query(
-		struct sip_msg *_m, char *_url, str *_dst, char *_post, char *_hdrs)
+int http_client_request(
+		sip_msg_t *_m, char *_url, str *_dst, char *_body, char *_hdrs, char *_met)
 {
 {
 	int res;
 	int res;
 	curl_query_t query_params;
 	curl_query_t query_params;
@@ -646,7 +651,7 @@ int http_client_query(
 	query_params.authmethod = default_authmethod;
 	query_params.authmethod = default_authmethod;
 	query_params.contenttype = NULL;
 	query_params.contenttype = NULL;
 	query_params.hdrs = _hdrs;
 	query_params.hdrs = _hdrs;
-	query_params.post = _post;
+	query_params.post = _body;
 	query_params.clientcert = NULL;
 	query_params.clientcert = NULL;
 	query_params.clientkey = NULL;
 	query_params.clientkey = NULL;
 	query_params.cacert = NULL;
 	query_params.cacert = NULL;
@@ -669,11 +674,21 @@ int http_client_query(
 		}
 		}
 	}
 	}
 
 
-	res = curL_query_url(_m, _url, _dst, &query_params);
+	res = curL_request_url(_m, _met, _url, _dst, &query_params);
 
 
 	return res;
 	return res;
 }
 }
 
 
+/*!
+ * Performs http_query and saves possible result (first body line of reply)
+ * to pvar.
+ * This is the same http_query as used to be in the utils module.
+ */
+int http_client_query(
+		struct sip_msg *_m, char *_url, str *_dst, char *_post, char *_hdrs)
+{
+	return http_client_request(_m, _url, _dst, _post, _hdrs, 0);
+}
 
 
 char *http_get_content_type(const str *connection)
 char *http_get_content_type(const str *connection)
 {
 {

+ 9 - 0
src/modules/http_client/functions.h

@@ -52,6 +52,15 @@ int curl_get_redirect(struct sip_msg *_m, const str *connection, str *result);
 int http_client_query(
 int http_client_query(
 		struct sip_msg *_m, char *_url, str *_dst, char *_post, char *_hdrs);
 		struct sip_msg *_m, char *_url, str *_dst, char *_post, char *_hdrs);
 
 
+/*
+ * Performs http request and saves possible result
+ * (first body line of reply) to pvar.
+ */
+int http_client_request(
+		sip_msg_t *_m, char *_url, str *_dst, char *_body, char *_hdrs, char *_met);
+
+
+
 
 
 char *http_get_content_type(const str *connection);
 char *http_get_content_type(const str *connection);
 
 

+ 111 - 0
src/modules/http_client/http_client.c

@@ -147,6 +147,8 @@ static int w_http_query_post(
 		struct sip_msg *_m, char *_url, char *_post, char *_result);
 		struct sip_msg *_m, char *_url, char *_post, char *_result);
 static int w_http_query_post_hdr(struct sip_msg *_m, char *_url, char *_post,
 static int w_http_query_post_hdr(struct sip_msg *_m, char *_url, char *_post,
 		char *_hdrs, char *_result);
 		char *_hdrs, char *_result);
+static int w_http_query_get_hdr(struct sip_msg *_m, char *_url, char *_body,
+		char *_hdrs, char *_result);
 static int w_curl_connect(
 static int w_curl_connect(
 		struct sip_msg *_m, char *_con, char *_url, char *_result);
 		struct sip_msg *_m, char *_con, char *_url, char *_result);
 
 
@@ -168,6 +170,9 @@ static cmd_export_t cmds[] = {
 	{"http_client_query", (cmd_function)w_http_query_post_hdr, 4, fixup_http_query_post_hdr,
 	{"http_client_query", (cmd_function)w_http_query_post_hdr, 4, fixup_http_query_post_hdr,
 		fixup_free_http_query_post_hdr,
 		fixup_free_http_query_post_hdr,
 		REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
 		REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
+	{"http_client_get", (cmd_function)w_http_query_get_hdr, 4, fixup_http_query_post_hdr,
+		fixup_free_http_query_post_hdr,
+		REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
 	{"http_connect", (cmd_function)w_curl_connect, 3, fixup_curl_connect,
 	{"http_connect", (cmd_function)w_curl_connect, 3, fixup_curl_connect,
 		fixup_free_curl_connect,
 		fixup_free_curl_connect,
 		REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
 		REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
@@ -1002,6 +1007,107 @@ static int w_http_query_post_hdr(
 	return w_http_query_script(_m, _url, _post, _hdrs, _result);
 	return w_http_query_script(_m, _url, _post, _hdrs, _result);
 }
 }
 
 
+/*!
+ * helper for HTTP-Query function
+ */
+static int ki_http_request_helper(sip_msg_t *_m, str *met, str *url, str *body,
+		str *hdrs, pv_spec_t *dst)
+{
+	int ret = 0;
+	str result = {NULL, 0};
+	pv_value_t val;
+
+	if(url==NULL || url->s==NULL) {
+		LM_ERR("invalid url parameter\n");
+		return -1;
+	}
+	ret = http_client_request(_m, url->s, &result,
+			(body && body->s && body->len>0)?body->s:NULL,
+			(hdrs && hdrs->s && hdrs->len>0)?hdrs->s:NULL,
+			(met && met->s && met->len>0)?met->s:NULL);
+
+	val.rs = result;
+	val.flags = PV_VAL_STR;
+	if(dst->setf) {
+		dst->setf(_m, &dst->pvp, (int)EQ_T, &val);
+	} else {
+		LM_WARN("target pv is not writable\n");
+	}
+
+	if(result.s != NULL)
+		pkg_free(result.s);
+
+	return (ret == 0) ? -1 : ret;
+}
+
+/*!
+ * KEMI function to perform GET with headers and body
+ */
+static int ki_http_get_hdrs(sip_msg_t *_m, str *url, str *body,
+		str *hdrs, str *dpv)
+{
+	str met = str_init("GET");
+	pv_spec_t *dst;
+
+	dst = pv_cache_get(dpv);
+	if(dst==NULL) {
+		LM_ERR("failed to get pv spec for: %.*s\n", dpv->len, dpv->s);
+		return -1;
+	}
+	if(dst->setf==NULL) {
+		LM_ERR("target pv is not writable: %.*s\n", dpv->len, dpv->s);
+		return -1;
+	}
+
+	return ki_http_request_helper(_m, &met, url, body, hdrs, dst);
+}
+
+/*!
+ * Wrapper for HTTP-Query function for cfg script
+ */
+static int w_http_get_script(sip_msg_t *_m, char *_url, char *_body,
+		char *_hdrs, char *_result)
+{
+	str met = str_init("GET");
+	str url = {NULL, 0};
+	str body = {NULL, 0};
+	str hdrs = {NULL, 0};
+	pv_spec_t *dst;
+
+	if(get_str_fparam(&url, _m, (gparam_p)_url) != 0 || url.len <= 0) {
+		LM_ERR("URL has no value\n");
+		return -1;
+	}
+	if(_body && get_str_fparam(&body, _m, (gparam_p)_body) != 0) {
+		LM_ERR("DATA has no value\n");
+		return -1;
+	} else {
+		if(body.len == 0) {
+			body.s = NULL;
+		}
+	}
+	if(_hdrs && get_str_fparam(&hdrs, _m, (gparam_p)_hdrs) != 0) {
+		LM_ERR("HDRS has no value\n");
+		return -1;
+	} else {
+		if(hdrs.len == 0) {
+			hdrs.s = NULL;
+		}
+	}
+	dst = (pv_spec_t *)_result;
+
+	return ki_http_request_helper(_m, &met, &url, &body, &hdrs, dst);
+}
+
+/*!
+ * Wrapper for HTTP-GET (HDRS-Variant)
+ */
+static int w_http_query_get_hdr(
+		sip_msg_t *_m, char *_url, char *_body, char *_hdrs, char *_result)
+{
+	return w_http_get_script(_m, _url, _body, _hdrs, _result);
+}
+
 /*!
 /*!
  * Parse arguments to  pv $curlerror
  * Parse arguments to  pv $curlerror
  */
  */
@@ -1149,6 +1255,11 @@ static sr_kemi_t sr_kemi_http_client_exports[] = {
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
 			SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE }
 			SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE }
 	},
 	},
+	{ str_init("http_client"), str_init("get_hdrs"),
+		SR_KEMIP_INT, ki_http_get_hdrs,
+		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
+			SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE }
+	},
 	{ str_init("http_client"), str_init("curl_connect"),
 	{ str_init("http_client"), str_init("curl_connect"),
 		SR_KEMIP_INT, ki_curl_connect,
 		SR_KEMIP_INT, ki_curl_connect,
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_STR,