1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "jsonrpc_internal.h" 35 36 #include "spdk/util.h" 37 38 struct jsonrpc_request { 39 const struct spdk_json_val *version; 40 const struct spdk_json_val *method; 41 const struct spdk_json_val *params; 42 const struct spdk_json_val *id; 43 }; 44 45 static int 46 capture_val(const struct spdk_json_val *val, void *out) 47 { 48 const struct spdk_json_val **vptr = out; 49 50 *vptr = val; 51 return 0; 52 } 53 54 static const struct spdk_json_object_decoder jsonrpc_request_decoders[] = { 55 {"jsonrpc", offsetof(struct jsonrpc_request, version), capture_val}, 56 {"method", offsetof(struct jsonrpc_request, method), capture_val}, 57 {"params", offsetof(struct jsonrpc_request, params), capture_val, true}, 58 {"id", offsetof(struct jsonrpc_request, id), capture_val, true}, 59 }; 60 61 static void 62 parse_single_request(struct spdk_jsonrpc_server_conn *conn, struct spdk_json_val *values) 63 { 64 bool invalid = false; 65 struct jsonrpc_request req = {}; 66 struct spdk_jsonrpc_request request; 67 68 request.conn = conn; 69 request.id = NULL; 70 71 if (spdk_json_decode_object(values, jsonrpc_request_decoders, 72 SPDK_COUNTOF(jsonrpc_request_decoders), 73 &req)) { 74 invalid = true; 75 goto done; 76 } 77 78 if (!req.version || req.version->type != SPDK_JSON_VAL_STRING || 79 !spdk_json_strequal(req.version, "2.0")) { 80 invalid = true; 81 } 82 83 if (!req.method || req.method->type != SPDK_JSON_VAL_STRING) { 84 req.method = NULL; 85 invalid = true; 86 } 87 88 if (req.id) { 89 if (req.id->type != SPDK_JSON_VAL_STRING && 90 req.id->type != SPDK_JSON_VAL_NUMBER && 91 req.id->type != SPDK_JSON_VAL_NULL) { 92 req.id = NULL; 93 invalid = true; 94 } else { 95 request.id = req.id; 96 } 97 } 98 99 if (req.params) { 100 if (req.params->type != SPDK_JSON_VAL_ARRAY_BEGIN && 101 req.params->type != SPDK_JSON_VAL_OBJECT_BEGIN) { 102 req.params = NULL; 103 invalid = true; 104 } 105 } 106 107 done: 108 if (invalid) { 109 spdk_jsonrpc_server_handle_error(&request, SPDK_JSONRPC_ERROR_INVALID_REQUEST); 110 } else { 111 spdk_jsonrpc_server_handle_request(&request, req.method, req.params); 112 } 113 } 114 115 static void 116 parse_batch_request(struct spdk_jsonrpc_server_conn *conn, struct spdk_json_val *values) 117 { 118 size_t num_values, i; 119 120 assert(values[0].type == SPDK_JSON_VAL_ARRAY_BEGIN); 121 num_values = values[0].len; 122 values++; 123 124 assert(conn->json_writer == NULL); 125 126 127 if (num_values == 0) { 128 struct spdk_jsonrpc_request error_request; 129 130 SPDK_TRACELOG(SPDK_TRACE_RPC, "empty batch array not allowed"); 131 132 /* Build a request with id = NULL since we don't have a valid request ID */ 133 error_request.conn = conn; 134 error_request.id = NULL; 135 spdk_jsonrpc_server_handle_error(&error_request, SPDK_JSONRPC_ERROR_INVALID_REQUEST); 136 return; 137 } 138 139 i = 0; 140 while (i < num_values) { 141 struct spdk_json_val *v = &values[i]; 142 143 parse_single_request(conn, v); 144 i += spdk_json_val_len(v); 145 } 146 147 if (conn->json_writer) { 148 /* 149 * There was at least one response - finish the batch array. 150 */ 151 spdk_json_write_array_end(conn->json_writer); 152 spdk_json_write_end(conn->json_writer); 153 conn->json_writer = NULL; 154 } 155 } 156 157 int 158 spdk_jsonrpc_parse_request(struct spdk_jsonrpc_server_conn *conn, void *json, size_t size) 159 { 160 struct spdk_jsonrpc_request error_request; 161 ssize_t rc; 162 void *end = NULL; 163 164 assert(conn->json_writer == NULL); 165 166 /* Build a request with id = NULL since we don't have a valid request ID */ 167 error_request.conn = conn; 168 error_request.id = NULL; 169 170 conn->batch = false; 171 172 /* Check to see if we have received a full JSON value. */ 173 rc = spdk_json_parse(json, size, NULL, 0, &end, 0); 174 if (rc == SPDK_JSON_PARSE_INCOMPLETE) { 175 return 0; 176 } else if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 177 SPDK_TRACELOG(SPDK_TRACE_RPC, "JSON parse error\n"); 178 spdk_jsonrpc_server_handle_error(&error_request, SPDK_JSONRPC_ERROR_PARSE_ERROR); 179 180 /* 181 * Can't recover from parse error (no guaranteed resync point in streaming JSON). 182 * Return an error to indicate that the connection should be closed. 183 */ 184 return -1; 185 } 186 187 /* Decode a second time now that there is a full JSON value available. */ 188 rc = spdk_json_parse(json, size, conn->values, SPDK_JSONRPC_MAX_VALUES, &end, 189 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE); 190 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 191 SPDK_TRACELOG(SPDK_TRACE_RPC, "JSON parse error on second pass\n"); 192 spdk_jsonrpc_server_handle_error(&error_request, SPDK_JSONRPC_ERROR_PARSE_ERROR); 193 return -1; 194 } 195 196 assert(end != NULL); 197 198 if (conn->values[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) { 199 parse_single_request(conn, conn->values); 200 } else if (conn->values[0].type == SPDK_JSON_VAL_ARRAY_BEGIN) { 201 conn->batch = true; 202 parse_batch_request(conn, conn->values); 203 } else { 204 SPDK_TRACELOG(SPDK_TRACE_RPC, "top-level JSON value was not array or object\n"); 205 spdk_jsonrpc_server_handle_error(&error_request, SPDK_JSONRPC_ERROR_INVALID_REQUEST); 206 } 207 208 return end - json; 209 } 210 211 static struct spdk_json_write_ctx * 212 begin_response(struct spdk_jsonrpc_server_conn *conn, const struct spdk_json_val *id) 213 { 214 struct spdk_json_write_ctx *w = conn->json_writer; 215 216 if (w == NULL) { 217 conn->json_writer = w = spdk_json_write_begin(spdk_jsonrpc_server_write_cb, conn, 0); 218 } 219 220 if (w == NULL) { 221 return NULL; 222 } 223 224 spdk_json_write_object_begin(w); 225 spdk_json_write_name(w, "jsonrpc"); 226 spdk_json_write_string(w, "2.0"); 227 228 if (id) { 229 spdk_json_write_name(w, "id"); 230 spdk_json_write_val(w, id); 231 } 232 233 return w; 234 } 235 236 static void 237 end_response(struct spdk_jsonrpc_server_conn *conn, struct spdk_json_write_ctx *w) 238 { 239 spdk_json_write_object_end(w); 240 241 if (!conn->batch) { 242 spdk_json_write_end(w); 243 spdk_jsonrpc_server_write_cb(conn, "\n", 1); 244 conn->json_writer = NULL; 245 } 246 } 247 248 struct spdk_json_write_ctx * 249 spdk_jsonrpc_begin_result(struct spdk_jsonrpc_request *request) 250 { 251 struct spdk_json_write_ctx *w; 252 253 w = begin_response(request->conn, request->id); 254 if (w == NULL) { 255 return NULL; 256 } 257 258 spdk_json_write_name(w, "result"); 259 260 return w; 261 } 262 263 void 264 spdk_jsonrpc_end_result(struct spdk_jsonrpc_request *request, struct spdk_json_write_ctx *w) 265 { 266 assert(w != NULL); 267 assert(w == request->conn->json_writer); 268 269 end_response(request->conn, w); 270 } 271 272 void 273 spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_request *request, 274 int error_code, const char *msg) 275 { 276 struct spdk_json_write_ctx *w; 277 struct spdk_json_val v_null; 278 const struct spdk_json_val *id; 279 280 id = request->id; 281 if (id == NULL) { 282 /* For error responses, if id is missing, explicitly respond with "id": null. */ 283 v_null.type = SPDK_JSON_VAL_NULL; 284 id = &v_null; 285 } 286 287 w = begin_response(request->conn, id); 288 if (w == NULL) { 289 return; 290 } 291 292 spdk_json_write_name(w, "error"); 293 spdk_json_write_object_begin(w); 294 spdk_json_write_name(w, "code"); 295 spdk_json_write_int32(w, error_code); 296 spdk_json_write_name(w, "message"); 297 spdk_json_write_string(w, msg); 298 spdk_json_write_object_end(w); 299 300 end_response(request->conn, w); 301 } 302 303 SPDK_LOG_REGISTER_TRACE_FLAG("rpc", SPDK_TRACE_RPC) 304