libwebsockets
Lightweight C library for HTML5 websockets
lws-jrpc.h
Go to the documentation of this file.
1
/*
2
* libwebsockets - small server side websockets and web server implementation
3
*
4
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
* of this software and associated documentation files (the "Software"), to
8
* deal in the Software without restriction, including without limitation the
9
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10
* sell copies of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
12
*
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
* IN THE SOFTWARE.
23
*
24
*
25
* This is a JSON-RPC parser and state management implementation that's:
26
*
27
* - Lightweight, it uses lws LEJP JSON stream parser for requests, responses,
28
* and user-defined parameter objects
29
*
30
* - Stateful... you can give it sequential input buffers randomly fragmented
31
* and it will complete when it has enough
32
*
33
* - Asynchronous... response processing can return to the event loop both
34
* while the RX is still coming and after it's all received before forming
35
* the response, eg, because it's querying on a remote connection to get the
36
* response data. Any number of RPCs can be either in flight or waiting for
37
* response processing to complete before responding.
38
*
39
* - Supports "version" extension
40
*
41
* - allows binding different method names to different callbacks
42
*
43
* - Supports both client and server roles, eg, can parse both requests and
44
* responses
45
*
46
* - No support for batch. Batching is not widely used because it doesn't
47
* add anything for the vast bulk of cases compared to sending n requests.
48
*
49
* This handles client and server RX and transaction state, creating a callback
50
* when parameters can be parsed and all of the request or notification is
51
* done.
52
*
53
* Producing JSON is usually simpler and more compact than expressing it as an
54
* object model, ie often a response can be completely formed in a single
55
* lws_snprintf(). Response JSON must be buffered on heap until the method
56
* callback is called with NULL / 0 buf len indicating that the incoming request
57
* has completed parsing.
58
*
59
*/
60
61
/* these are opaque */
62
63
struct
lws_jrpc_obj;
64
struct
lws_jrpc;
65
66
typedef
enum
{
67
LJRPC_CBRET_CONTINUE
,
68
LJRPC_CBRET_WANT_TO_EMIT
,
69
LJRPC_CBRET_FINISHED
,
70
LJRPC_CBRET_FAILED
71
} lws_jrpc_cb_return_t;
72
73
/*
74
* method name to lejp parsing handler map
75
*/
76
77
typedef
struct
lws_jrpc_method
{
78
const
char
*
method_name
;
79
const
char
*
const
*
paths
;
80
lejp_callback
cb
;
81
int
count_paths
;
82
} lws_jrpc_method_t;
83
84
/*
85
* Boilerplate for forming correct requests
86
*/
87
88
/* Boilerplate to start a request */
89
#
define
LWSJRPCBP_REQ_START_S
"{\"jsonrpc\":\"2.0\",\"method\":\"%s\""
90
/* Boilerplate to start parameters (params are left freeform for user) */
91
#
define
LWSJRPCBP_REQ_VERSION_S
",\"version\":\"%s\""
92
/* Boilerplate to start parameters (params are left freeform for user) */
93
#
define
LWSJRPCBP_REQ_PARAMS
",\"params\":"
94
/* Boilerplate to complete the result object */
95
#
define
LWSJRPCBP_REQ_NOTIF_END
"}"
96
/* Boilerplate to complete the result object */
97
#
define
LWSJRPCBP_REQ_ID_END_S
",\"id\":%s}"
98
99
/*
100
* Boilerplate for forming correct responses
101
*/
102
103
/* Boilerplate to start a result */
104
#
define
LWSJRPCBP_RESP_RESULT
"{\"jsonrpc\":\"2.0\",\"result\":"
105
/* Boilerplate to complete the result object */
106
#
define
LWSJRPCBP_RESP_ID_END_S
",\"id\":%s}"
107
108
/* Boilerplate to form an error */
109
#
define
LWSJRPCBP_RESP_ERROR_D
"{\"jsonrpc\":\"2.0\",\"error\":{\"code\":%d"
110
/* optional */
111
#
define
LWSJRPCBP_RESP_ERROR_MSG_S
",\"message\":\"%s\""
112
/* optional */
113
#
define
LWSJRPCBP_RESP_ERROR_DATA
",\"data\":"
114
/* required */
115
#
define
LWSJRPCBP_RESP_ERROR_END
"}"
116
117
/*
118
* JSONRPC Well-known Errors
119
*/
120
121
enum
{
122
LWSJRPCE__NO_ERROR
= 0,
123
124
LWSJRPCWKE__PARSE_ERROR
= -32700,
/* invalid JSON */
125
LWSJRPCWKE__INVALID_REQUEST
= -32600,
/* not valid JSONRPC object */
126
LWSJRPCWKE__METHOD_NOT_FOUND
= -32601,
/* method not supported */
127
LWSJRPCWKE__INVALID_PARAMS
= -32602,
/* parameters are invalid */
128
LWSJRPCWKE__INTERNAL_ERROR
= -32603,
/* internal JSONRPC error */
129
LWSJRPCWKE__SERVER_ERROR_FIRST
= -32000,
/* implementation-defined...*/
130
LWSJRPCWKE__SERVER_ERROR_LAST
= -32099,
/* ... server errors range */
131
132
LWSJRPCE__INVALID_MEMBERS
= -31000,
/* reponse membs in req, vv */
133
};
134
135
enum
{
136
LWSJRPC_PARSE_REQUEST
,
137
LWSJRPC_PARSE_RESPONSE
138
};
139
140
/*
141
* APIs for the opaque JRPC request object
142
*/
143
144
/**
145
* lws_jrpc_obj_parse() - parse a request or response
146
*
147
* \param jrpc: the jrpc context this belongs to
148
* \param type: LWSJRPC_PARSE_REQUEST or ..._RESPONSE
149
* \param opaque: user-defined pointer bound to lws_jrpc, ignored by lws
150
* \param buf: chunk of JSON-RPC
151
* \param l: remaining length of JSON (may be under or oversize)
152
* \param r: NULL to indicate starting new req, already set means continue parse
153
*
154
* If necessary creates an opaque req object and starts parsing len bytes of
155
* buf. This may be undersize (more parts coming) in which case \p req will be
156
* set on entry next time indicating a continuation.
157
*
158
* \p type and \p opaque are ignored if it it's not the first buffer that
159
* creates the req object.
160
*
161
* Return code is >= 0 if completed, representing the amount of unused data in
162
* the input buffer. -1 indicates more input data needed, <-1 indicates an
163
* error from the LWSJRPCWKE_ set above, or LEJP_REJECT_UNKNOWN for OOM
164
*/
165
166
LWS_VISIBLE LWS_EXTERN
int
167
lws_jrpc_obj_parse
(
struct
lws_jrpc *jrpc,
int
type,
void
*opaque,
168
const
char
*buf, size_t l,
struct
lws_jrpc_obj **r);
169
170
/*
171
* lws_jrpc_obj_destroy() - detach and destroy a JRPC request or response
172
*
173
* \param _r: pointer to pointer to JRPC request to detach and free
174
*
175
* Detaches the req from its JRPC context and frees it and any internal
176
* allocations.
177
*/
178
LWS_VISIBLE LWS_EXTERN
void
179
lws_jrpc_obj_destroy
(
struct
lws_jrpc_obj **_r);
180
181
/*
182
* lws_jrpc_obj_get_opaque() - retreive the opaque pointer bound to the req
183
*
184
* \param r: pointer to pointer to JRPC request
185
*
186
* Returns the opaque pointer for a req given when it was parsed / created.
187
*/
188
LWS_VISIBLE LWS_EXTERN
void
*
189
lws_jrpc_obj_get_opaque
(
const
struct
lws_jrpc_obj *r);
190
191
/*
192
* lws_jrpc_obj_id() - retreive the object's id string
193
*
194
* \param r: pointer to pointer to JRPC object
195
*
196
* Returns a pointer to a correctly-typed id for use in a response; if a string,
197
* then it is already quoted, if an int or null then it's provided without
198
* quotes.
199
*/
200
LWS_VISIBLE LWS_EXTERN
const
char
*
201
lws_jrpc_obj_id
(
const
struct
lws_jrpc_obj *r);
202
203
204
/*
205
* APIs for the opaque JRPC context
206
*/
207
208
/**
209
* lws_jrpc_create() - Allocate and initialize a JRPC context
210
*
211
* \param methods: the method callbacks and names we can process
212
* \param opaque: user-defined pointer bound to lws_jrpc ignored by lws
213
*
214
* Allocates an opaque lws_jrpc object and binds it to the given array of
215
* method names and callbacks
216
*/
217
LWS_VISIBLE LWS_EXTERN
struct
lws_jrpc *
218
lws_jrpc_create
(
const
lws_jrpc_method_t *methods,
void
*opaque);
219
220
/*
221
* lws_jrpc_destroy() - destroy an allocated JRPC context
222
*
223
* \param jrpc: pointer to pointer to jrpc to destroy
224
*
225
* Destroys any ongoing reqs in the JRPC and then destroys the JRPC and sets the
226
* given pointer to NULL.
227
*/
228
LWS_VISIBLE LWS_EXTERN
void
229
lws_jrpc_destroy
(
struct
lws_jrpc **jrpc);
include
libwebsockets
lws-jrpc.h
Generated on Fri Jun 17 2022 04:56:33 for libwebsockets by
1.9.1