Featured image of post kamailio的HTTP功能(一)

kamailio的HTTP功能(一)

http 模块

kamailio的http功能十分丰富,提供了客户端和服务端。对应的模块有:

client 描述
HTTP_CLIENT 依赖libcurl
HTTP_ASYNC_CLIENT 异步client,依赖libcurl 和libevent
JSONRPCC 依赖libjson,libevent,glibc
JANSSONRPCC 依赖jansson,libevent
server 描述
JSONRPCS 支持http,fifo, datagram
MICROHTTPD 依赖libmcrohttpd
XHTTP 提供http/1.0基础服务
XHTTP_PI 通过kamailio的API提供数据库操作
XHTTP_PROM 为prometheus提供metrics数据
XHTTP_RPC 通过http方式 提供rpc服务

本章主要是介绍client模块,版本为:

version: kamailio 5.8.5 (x86_64/linux)

Client

HTTP_CLIENT 模块

支持http和https协议,同步请求

  1. http配置
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 302是否重定向, 默认为:1
modparam("http_client", "httpredirect", 0) 
# useragent 设置
modparam("http_client", "useragent", "Secret HTTP REST grabber 0.42")
# maxdatasize  reponse body的最大大小,默认0,不设置
modparam("http_client", "maxdatasize", 2000)
# connection_timeout 等待服务端返回的超时时间,默认4s,单位是秒还是毫秒,由timeout_mode决定
modparam("http_client", "connection_timeout", 5)
# timeout_mode  0,超时功能不能用 1,表示单位是秒,2,表示单位是毫秒,默认1
modparam("http_client", "timeout_mode", 1)
# keep_connections 0,请求之后关闭连接;1,请求之后保持连接
modparam("http_client", "keep_connections", 1)
# query_result 控制http_client_query的返回结果, 0,返回整个body;1,返回body的第一行,默认1 
modparam("http_client", "query_result", 0)
  1. https
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
modparam("http_client", "client_cert", "/var/certs/sollentuna.example.com.cert")
modparam("http_client", "client_key", "/var/certs/sollentuna.example.com.key")
# 验证服务端证书,默认1 
modparam("http_client", "verify_peer", 1)
# 验证domain,默认2
modparam("http_client", "verify_host", 2)
#tls版本 0,libcurl默认; 1,TLSv1; 2,SSLv2; 3,SSLv3; 4,TLSv1.0; 5,TLSv1.1; 6,TLSv1.2
modparam("http_client", "tlsversion", 6)
# http认证方式,默认3(1+2) 1,BASIC authention; 2,HTTP Digest authentication; 4,GSS-Negotiate authentication; 8, NTLM authentication; 16,HTTP Digest with IE flavour
modparam("http_client", "authmethod", 3)

https的配置也可以从文件读取

1
modparam("http_client", "config_file", "httpconnections.cfg)

httpconnections.cfg

1
2
3
4
5
6
7
8
9
[authapiserver]
url = https://api.runbo.example.com/v4.2/auth
timeout = 1
maxdatasize = 4
tlsversion = TLSv1.2
verify_peer = yes
client_key = default_key.pem
client_cert = default_cert.pem
http_follow_redirect = no
  1. 设置http server的url
1
2
3
4
modparam("http_client", "httpcon", "apione=>http://atlanta.example.com")
modparam("http_client", "httpcon", "apitwo=>http://atlanta.example.com/api/12")
modparam("http_client", "httpcon", "apithree=>http://annabella:mysecret@atlanta.example.com/api/12")
modparam("http_client", "httpcon", "apifour=>http://stockholm.example.com/api/getstuff;timeout=12;failover=apione")
  1. 几个请求函数
  • http_connect(connection, url, [content_type, data,] result)
1
2
3
4
5
modparam("http_client", "httpcon", "apiserver=>https://kamailio.org/api/");
#POST 
$var(res) = http_connect("apiserver", "/mailbox", "application/json", "{ ok, {200, ok}}", "$avp(gurka)");
#GET 
$var(res) = http_connect("apiserver", "/mailbox?page=1&&limit=10","$avp(gurka)");

默认是GET方式, POST方式,需要设置content_typedata,只能被用到REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE,BRANCH_ROUTE

  • http_connect_raw(connection, url, content_type, data, result)
1
$var(res) = http_connect_raw("apiserver", "/mailbox", "application/json", "{ ok, {200, ok}}", "$avp(gurka)");

只能发送POST,可以使用的路由有:REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE

  • http_client_query(url, [post-data], [hdrs], result)
1
2
3
4
5
6
#GET 
http_client_query("http://api.com/index.php?r_uri=$(ru{s.escape.param})&f_uri=$(fu{s.escape.param})",
	   "$var(result)");
# POST-Request
http_client_query("http://api.com/index.php", "src=$si",
    "Content-Type: text/plain", "$var(result)");

可以发送GETPOST, POST就设置post-data,可以用在ANY ROUTE.

  • http_client_get(url, body, hdrs, respv)
1
2
http_client_get("http://api.com/index.php?r_uri=$(ru{s.escape.param})&f_uri=$(fu{s.escape.param})",
	   "", "X-Token: abc", "$var(result)");

只能GET, body为空,可以用在ANY ROUTE.

HTTP_ASYNC_CLIENT 模块

异步请求,支持http和https两种方式

  1. http配置
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#多少个worker来发送请求和处理返回,默认1个
modparam("http_async_client", "workers", 2)
# 等待服务端返回的超时时间,单位毫秒,默认500ms
modparam("http_async_client", "connection_timeout", 1000)
# hash_size, 默认2048
modparam("http_async_client", "hash_size", 1024)

modparam("http_async_client", "tcp_keepalive", 1)
# 保持keepalive的时间,单位秒,空闲等待时间,默认60s
modparam("http_async_client", "tcp_ka_idle", 30)
# 保持keepalive的间隔时间,单位秒,默认60s
modparam("http_async_client", "tcp_ka_interval", 120)
  1. https 配置
1
2
3
4
5
6
7
8
# tls的版本
modparam("http_async_client", "tls_version", 6)
# 是否验证domain,默认2 
modparam("http_async_client", "tls_verify_host", 0)
# 是否验证服务端证书,默认1
modparam("http_async_client", "tls_verify_peer", 0)
modparam("http_async_client", "tls_client_cert", "/etc/kamailio/ssl/clientcert.pem")
modparam("http_async_client", "tls_client_key", "/etc/kamailio/ssl/clientcert.key")
  1. 重要函数介绍
  • http_async_query(url, route_name)

支持GETPOST, 可以用在ANY ROUTE.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# GET
http_async_query("http://example.com/test.php?r_uri=$rU&f_uri=$fU", "HTTP_REPLY");
...
# POST
$http_req(body) = "{'r_uri':'" + $rU + "', 'f_uri':'" + $fU + "'}";
http_async_query("http://example.com/test.php", "HTTP_REPLY");
···
route[HTTP_REPLY] {
    if ($http_ok) {
        xlog("L_INFO", "route[HTTP_REPLY]: status $http_rs\n");
        xlog("L_INFO", "route[HTTP_REPLY]: body   $http_rb\n");
    } else {
        xlog("L_INFO", "route[HTTP_REPLY]: error  $http_err)\n");
    }
}
  1. 重要变量介绍
  • http_req(key),只能写,key有以下几种:

    • all: 设置成$null, 重置所有的变量
    • hdr: 设置/修改/删除 http header,设置多次,可以添加多个头
    • body: 设置/修改/删除 http body
    • method: 设置请求方式:GET,POST,PUT,DELETE, 不设置的话,就是GET,有body就是POST
    • timeout: 设置超时时间
    • tls_client_cert: 设置客户端证书
    • tls_client_key: 设置客户端证书的key
    • tls_ca_path: ca证书路径
    • authmethod: 设置认证方式
    • username: 设置认证用户名
    • password: 设置认证密码
    • suspend: 设置为0,不会停止当前的事务
    • tcp_keepalive: 设置为1,开启keepalive
    • tcp_ka_idle: 设置keepalive的等待时间,单位秒,默认60s
    • tcp_ka_interval: 设置keepalive的间隔时间,单位秒,默认60s
    • follow_redirect: 设置为1,开启重定向
  • http_X: 只读,

    • $http_ok: 1 请求成功;0失败
    • $http_rs: http状态码
    • $http_err: 请求出错,$null 表示没有出错
    • $http_rr: http reason 解析
    • $http_hdr(name): 获取http header
    • $http_mb$http_ml: response的buffer和长度
    • $http_rb$http_bs: response的body和长度
    • $http_time: http请求的响应时间,单位毫秒

JSONRPCC 模块

JSONRPC是JSON格式HTTP协议下RESTful风格的RPC协议。 使用较简单。

  1. 配置解析:
1
2
3
4
#配置server地址,可配多个,格式"host1:port1,priority1 host2:port2,priority2"
modparam("jsonrpcc", "servers", "localhost:9999,2 10.10.0.1:9999,2 backup.server:9999,1")
# 最大重试次数,-1 一直重连, 0 不重试
modparam("jsonrpcc", "max_conn_attempts", 10)
  1. 关键函数
  • jsonrpc_notification(method, parameters)

事件通知,不需要返回值。

1
jsonrpc_notification("update_user", "{'id': 1234, 'name': 'Petros'}")
  • jsonrpc_request(method, parameters, return_route, error_route, result_var)

获取返回值,可以通过这个函数来实现kamctl的功能。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
jsonrpc_request("get_user", "{'id': 1234}", "RESPONSE", "ERROR", "$var(result)");
...
route[RESPONSE] {
	xlog("Result received: $var(result)");
	...
}
...
route[ERROR] {
	xlog("Error received: $var(result)");
	...
}

JANSSONRPCC 模块

  1. 配置解析:
1
2
3
4
5
6
# 返回值存储位置,默认:$var(jsrpc_result)
modparam("janssonrpcc", "result_pv", "$var(result)")
# 重试的错误码,默认: -32603, -32000..-32099
modparam("janssonrpcc", "retry_codes", "-32603, -32000..-32099");
# keepalive时间,默认: 10
modparam("janssonrpcc", "keep_alive", 10)

server端配置方式:

1
2
3
4
modparam("janssonrpcc", "server", "conn=tests;srv=_test1._tcp.example.net");
modparam("janssonrpcc", "server", "conn=tests;srv=_test2._tcp.example.net");
modparam("janssonrpcc", "server", "conn=local;addr=localhost;port=8080;priority=10;weight=10");
modparam("janssonrpcc", "server", "conn=user_db;addr=rpc.prod.example.net;port=5060;priority=10;weight=10");
  1. 关键函数
  • janssonrpc_notification(conn, method, parameters)

通知函数,不需要返回值。

  • janssonrpc_request(conn, method, params[, options]])

json请求函数,可以用在ANY ROUTE,示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
route {
	janssonrpc_request("user_db", "get_user", '{"id": 1234}', "route=RESPONSE;retry=1");
}

route[RESPONSE] {
	if(jansson_get("internal_error", $var(jsrpc_result), "$var(internal)")) {
		route(INTERNAL);
	} else if(jansson_get("error", $var(jsrpc_result), "$var(error)")) {
		route(ERROR);
	} else if(jansson_get("result", $var(jsrpc_result), "$var(result)")) {
		route(RESULT);
	}
    t_reply("200", "OK");
}

route[RESULT] {
	xlog("result is $var(result)\n");
	xlog("success\n");
}

route[ERROR] {
	xlog("There was an error\n");
	if(jansson_get("code", $var(error), "$var(c)")) {
		xlog("code is $var(c)\n");
	}

	if(jansson_get("message", $var(error), "$var(r)")) {
		xlog("error is $var(r)\n");
	}

	if(jansson_get("data", $var(error), "$var(d)")) {
		xlog("data is $var(d)\n");
	}
}

route[INTERNAL] {
	xlog("There was an internal error\n");

	jansson_get("code", $var(internal), "$var(c)");
	xlog("code is $var(c)\n");

	jansson_get("message", $var(internal), "$var(r)");
	xlog("error is $var(r)\n");

	if(jansson_get("data", $var(internal), "$var(d)")) {
		xlog("request is $var(d)\n");
	}
}
本博客已稳定运行
发表了26篇文章 · 总计45.09k字
本站总访问量 次 · 您是本站第 位访问者
粤ICP备2025368587号-1| 使用 Hugo 构建
主题 StackJimmy 设计