fix
[libexssl.git] / test / jsonrpc_srv.c
blob8bb2ff28ceebb375be38b19cb34e03d9ab3d2677
1 #include "sslnet.h"
2 #include "linenoise.h"
4 net_srv_t *srv;
5 int is_active = 1;
6 jsonrpc_method_array_t *methods;
7 ev_id_t id_conn = 0;
8 pthread_rwlock_t locker;
10 static void sigexit (int sig) {
11 if (SIGTERM == sig || SIGINT == sig) {
12 is_active = 0;
13 sslws_srv_done(srv);
14 free(methods);
18 static void _connect () {
19 if (!is_active)
20 return;
21 pthread_rwlock_wrlock(&locker);
22 while (0 == id_conn) {
23 id_conn = net_ev_connect(srv, CONST_STR_LEN("ws://127.0.0.1:7878/api/v2"));
24 sleep(8);
26 pthread_rwlock_unlock(&locker);
29 static void setsig () {
30 struct sigaction sa;
31 sa.sa_handler = sigexit;
32 sa.sa_flags = 0;
33 sigemptyset(&sa.sa_mask);
34 sigaction(SIGTERM, &sa, NULL);
35 sigaction(SIGINT, &sa, NULL);
38 static int on_handle (ev_buf_t *ev) {
39 int rc = NET_ERROR;
40 ws_t *ws = &ev->data.ws;
41 if (!WS_ISFIN(ws) || WS_TEXT != WS_OPCODE(ws))
42 return NET_OK;
43 if (!jsonrpc_is_response(&ev->data.json.jsonrpc)) {
44 if ((rc = jsonrpc_execute_parsed(&ev->buf, WS_EV_OFFSET(ev), methods, ev, &ev->data.json.jsonrpc)) < 0)
45 rc = ws_ev_send(srv, ev->id, 0, ev->buf.ptr, ev->buf.len, WS_FIN, WS_TEXT);
46 else
47 rc = NET_OK;
48 } else {
49 size_t off = WS_EV_OFFSET(ev);
50 char *s = strndup(ev->buf.ptr + off, ev->buf.len - off);
51 printf("%s\n", s);
52 free(s);
53 rc = NET_OK;
55 if (0 == rc)
56 return NET_OK;
57 return NET_ERROR;
60 static void *on_start (void *param) {
61 ws_srv_start(srv);
62 return NULL;
65 static int cb_login (strbuf_t *buf, void *userdata) {
66 cstr_t *str = userdata;
67 json_begin_object(buf);
68 json_add_str(buf, CONST_STR_LEN("login"), str->ptr, str->len, JSON_END);
69 json_end_object(buf);
70 return 0;
73 static int login (strbuf_t *buf, json_item_t **params, size_t params_len, intptr_t id, int id_len, void *userdata) {
74 cstr_t *s_login = mkcstr(params[0]->data.s.ptr, params[0]->data.s.len);
75 ev_buf_t *ev = userdata;
76 ws_jsonrpc_response_send(srv, ev->id, buf, id, id_len, cb_login, s_login);
77 free(s_login);
78 return 0;
81 static int cb_ok (strbuf_t *buf, void *dummy) {
82 json_add_true(buf, CONST_STR_NULL, JSON_END);
83 return 0;
86 static int getprops (strbuf_t *buf, json_item_t **params, size_t params_len, intptr_t id, int id_len, void *userdata) {
87 ev_buf_t *ev = userdata;
88 ws_jsonrpc_response_send(srv, ev->id, buf, id, id_len, cb_ok, NULL);
89 return 0;
92 static int notify (strbuf_t *buf, json_item_t **params, size_t params_len, intptr_t id, int id_len, void *userdata) {
93 char *s = strndup(params[0]->data.s.ptr, params[0]->data.s.len);
94 printf("NOTIFY: %s\n", s);
95 free(s);
96 return 0;
99 static int on_login (strbuf_t *buf, void *dummy) {
100 char *s;
101 s = linenoise("login: ", NULL);
102 json_add_str(buf, CONST_STR_NULL, s, strlen(s), JSON_NEXT);
103 s = linenoise("pass: ", NULL);
104 json_add_str(buf, CONST_STR_NULL, s, strlen(s), JSON_END);
105 return 0;
108 static int on_notify (strbuf_t *buf, void *dummy) {
109 char *s = linenoise("notify: ", NULL);
110 json_add_str(buf, CONST_STR_NULL, s, strlen(s), JSON_END);
111 return 0;
114 json_t *_send (char *method, size_t method_len, uint32_t flags, strbuf_t *buf, jsonrpc_h cb, void *userdata) {
115 json_t *json = NULL;
116 while (1) {
117 if (!is_active)
118 return NULL;
119 pthread_rwlock_rdlock(&locker);
120 if (id_conn > 0)
121 json = ws_jsonrpc_request_send(srv, id_conn, method, method_len, flags, buf, cb, userdata);
122 pthread_rwlock_unlock(&locker);
123 if (json && -1 != (intptr_t)json)
124 return json;
125 if (errno == EBADF)
126 _connect();
127 else
128 return json;
132 static void term () {
133 char *method;
134 strbuf_t buf;
135 json_t *json = NULL;
136 memset(&buf, 0, sizeof buf);
137 do {
138 method = linenoise("> ", NULL);
139 if (method && '\0' != *method && 0 != strcmp(method, "quit")) {
140 int method_len = strlen(method);
141 if (0 == strcmp(method, "login"))
142 json = _send(method, method_len, NF_SYNC, &buf, on_login, NULL);
143 else
144 if (0 == strcmp(method, "getProps"))
145 json = _send(method, method_len, 0, &buf, NULL, NULL);
146 else
147 if (0 == strcmp(method, "notify"))
148 json = _send(method, method_len, NF_NOTIFY, &buf, on_notify, NULL);
149 else
150 if (0 == strcmp(method, "none"))
151 json = _send(method, method_len, NF_SYNC, &buf, NULL, NULL);
152 if (json && -1 != (intptr_t)json) {
153 printf("%s\n", buf.ptr);
154 json_free(json);
155 json = NULL;
157 if (buf.ptr) {
158 free(buf.ptr);
159 memset(&buf, 0, sizeof buf);
162 } while (0 != strcmp(method, "quit"));
163 if (json && -1 != (intptr_t)json)
164 json_free(json);
165 if (buf.ptr)
166 free(buf.ptr);
167 ws_ev_disconnect(srv, id_conn);
168 ws_srv_done(srv);
171 int login_args [] = { JSON_STRING, JSON_STRING };
172 int getprops_args [] = {};
173 int notify_args [] = { JSON_STRING };
175 int main (int argc, const char *argv[]) {
176 int is_client = 1;
177 if (2 != argc) return 1;
178 if (0 == strcmp(argv[1], "server"))
179 is_client = 0;
180 else
181 if (0 != strcmp(argv[1], "client"))
182 return 1;
183 printf("[%d]\n", getpid());
184 methods = jsonrpc_init_methods();
185 jsonrpc_add_method(methods, 1, CONST_STR_LEN("login"), login, JSONRPC_TYPES_LEN(login_args));
186 jsonrpc_add_method(methods, 2, CONST_STR_LEN("getProps"), getprops, JSONRPC_TYPES_LEN(getprops_args));
187 jsonrpc_add_method(methods, 3, CONST_STR_LEN("notify"), notify, JSONRPC_TYPES_LEN(notify_args));
188 if (is_client) {
189 pthread_t th;
190 srv = sslws_jsonrpc_srv_init(NULL, "./fullchain.pem", "./privkey.pem");
191 srv->on_handle = on_handle;
192 srv->tm_connect = 8;
193 srv->tm_recv = 8;
194 pthread_create(&th, NULL, on_start, NULL);
195 sleep(1);
196 if (0 == (id_conn = net_ev_connect(srv, CONST_STR_LEN("wss://127.0.0.1:7878/api/v2")))) {
197 printf("(%d) %s\n", errno, strerror(errno));
198 sslws_srv_done(srv);
199 free(methods);
200 } else
201 term();
202 } else {
203 setsig();
204 srv = sslws_jsonrpc_srv_init("7878", "./fullchain.pem", "./privkey.pem");
205 srv->on_handle = on_handle;
206 srv->on_check_url = check_api_ver;
207 srv->tm_ping = 60;
208 printf("Ok\n");
209 ws_srv_start(srv);
211 return 0;