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 67 if (spdk_json_decode_object(values, jsonrpc_request_decoders, 68 SPDK_COUNTOF(jsonrpc_request_decoders), 69 &req)) { 70 invalid = true; 71 goto done; 72 } 73 74 if (!req.version || req.version->type != SPDK_JSON_VAL_STRING || 75 !spdk_json_strequal(req.version, "2.0")) { 76 invalid = true; 77 } 78 79 if (!req.method || req.method->type != SPDK_JSON_VAL_STRING) { 80 req.method = NULL; 81 invalid = true; 82 } 83 84 if (req.id) { 85 if (req.id->type != SPDK_JSON_VAL_STRING && 86 req.id->type != SPDK_JSON_VAL_NUMBER && 87 req.id->type != SPDK_JSON_VAL_NULL) { 88 req.id = NULL; 89 invalid = true; 90 } 91 } 92 93 if (req.params) { 94 if (req.params->type != SPDK_JSON_VAL_ARRAY_BEGIN && 95 req.params->type != SPDK_JSON_VAL_OBJECT_BEGIN) { 96 req.params = NULL; 97 invalid = true; 98 } 99 } 100 101 done: 102 if (invalid) { 103 spdk_jsonrpc_server_handle_error(conn, SPDK_JSONRPC_ERROR_INVALID_REQUEST, req.method, req.params, 104 req.id); 105 } else { 106 spdk_jsonrpc_server_handle_request(conn, req.method, req.params, req.id); 107 } 108 } 109 110 static void 111 parse_batch_request(struct spdk_jsonrpc_server_conn *conn, struct spdk_json_val *values) 112 { 113 size_t num_values, i; 114 115 assert(values[0].type == SPDK_JSON_VAL_ARRAY_BEGIN); 116 num_values = values[0].len; 117 values++; 118 119 assert(conn->json_writer == NULL); 120 121 if (num_values == 0) { 122 SPDK_TRACELOG(SPDK_TRACE_RPC, "empty batch array not allowed"); 123 spdk_jsonrpc_server_handle_error(conn, SPDK_JSONRPC_ERROR_INVALID_REQUEST, NULL, NULL, NULL); 124 return; 125 } 126 127 i = 0; 128 while (i < num_values) { 129 struct spdk_json_val *v = &values[i]; 130 131 parse_single_request(conn, v); 132 i += spdk_json_val_len(v); 133 } 134 135 if (conn->json_writer) { 136 /* 137 * There was at least one response - finish the batch array. 138 */ 139 spdk_json_write_array_end(conn->json_writer); 140 spdk_json_write_end(conn->json_writer); 141 conn->json_writer = NULL; 142 } 143 } 144 145 int 146 spdk_jsonrpc_parse_request(struct spdk_jsonrpc_server_conn *conn, void *json, size_t size) 147 { 148 ssize_t rc; 149 void *end = NULL; 150 151 assert(conn->json_writer == NULL); 152 153 conn->batch = false; 154 155 /* Check to see if we have received a full JSON value. */ 156 rc = spdk_json_parse(json, size, NULL, 0, &end, 0); 157 if (rc == SPDK_JSON_PARSE_INCOMPLETE) { 158 return 0; 159 } else if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 160 SPDK_TRACELOG(SPDK_TRACE_RPC, "JSON parse error\n"); 161 spdk_jsonrpc_server_handle_error(conn, SPDK_JSONRPC_ERROR_PARSE_ERROR, NULL, NULL, NULL); 162 163 /* 164 * Can't recover from parse error (no guaranteed resync point in streaming JSON). 165 * Return an error to indicate that the connection should be closed. 166 */ 167 return -1; 168 } 169 170 /* Decode a second time now that there is a full JSON value available. */ 171 rc = spdk_json_parse(json, size, conn->values, SPDK_JSONRPC_MAX_VALUES, &end, 172 SPDK_JSON_PARSE_FLAG_DECODE_IN_PLACE); 173 if (rc < 0 || rc > SPDK_JSONRPC_MAX_VALUES) { 174 SPDK_TRACELOG(SPDK_TRACE_RPC, "JSON parse error on second pass\n"); 175 spdk_jsonrpc_server_handle_error(conn, SPDK_JSONRPC_ERROR_PARSE_ERROR, NULL, NULL, NULL); 176 return -1; 177 } 178 179 assert(end != NULL); 180 181 if (conn->values[0].type == SPDK_JSON_VAL_OBJECT_BEGIN) { 182 parse_single_request(conn, conn->values); 183 } else if (conn->values[0].type == SPDK_JSON_VAL_ARRAY_BEGIN) { 184 conn->batch = true; 185 parse_batch_request(conn, conn->values); 186 } else { 187 SPDK_TRACELOG(SPDK_TRACE_RPC, "top-level JSON value was not array or object\n"); 188 spdk_jsonrpc_server_handle_error(conn, SPDK_JSONRPC_ERROR_INVALID_REQUEST, NULL, NULL, NULL); 189 } 190 191 return end - json; 192 } 193 194 static struct spdk_json_write_ctx * 195 begin_response(struct spdk_jsonrpc_server_conn *conn, const struct spdk_json_val *id) 196 { 197 struct spdk_json_write_ctx *w = conn->json_writer; 198 199 if (w == NULL) { 200 conn->json_writer = w = spdk_json_write_begin(spdk_jsonrpc_server_write_cb, conn, 0); 201 } 202 203 if (w == NULL) { 204 return NULL; 205 } 206 207 spdk_json_write_object_begin(w); 208 spdk_json_write_name(w, "jsonrpc"); 209 spdk_json_write_string(w, "2.0"); 210 211 if (id) { 212 spdk_json_write_name(w, "id"); 213 spdk_json_write_val(w, id); 214 } 215 216 return w; 217 } 218 219 static void 220 end_response(struct spdk_jsonrpc_server_conn *conn, struct spdk_json_write_ctx *w) 221 { 222 spdk_json_write_object_end(w); 223 224 if (!conn->batch) { 225 spdk_json_write_end(w); 226 spdk_jsonrpc_server_write_cb(conn, "\n", 1); 227 conn->json_writer = NULL; 228 } 229 } 230 231 struct spdk_json_write_ctx * 232 spdk_jsonrpc_begin_result(struct spdk_jsonrpc_server_conn *conn, const struct spdk_json_val *id) 233 { 234 struct spdk_json_write_ctx *w; 235 236 w = begin_response(conn, id); 237 if (w == NULL) { 238 return NULL; 239 } 240 241 spdk_json_write_name(w, "result"); 242 243 return w; 244 } 245 246 void 247 spdk_jsonrpc_end_result(struct spdk_jsonrpc_server_conn *conn, struct spdk_json_write_ctx *w) 248 { 249 assert(w != NULL); 250 assert(w == conn->json_writer); 251 252 end_response(conn, w); 253 } 254 255 void 256 spdk_jsonrpc_send_error_response(struct spdk_jsonrpc_server_conn *conn, 257 const struct spdk_json_val *id, 258 int error_code, const char *msg) 259 { 260 struct spdk_json_write_ctx *w; 261 struct spdk_json_val v_null; 262 263 if (id == NULL) { 264 /* For error responses, if id is missing, explicitly respond with "id": null. */ 265 v_null.type = SPDK_JSON_VAL_NULL; 266 id = &v_null; 267 } 268 269 w = begin_response(conn, id); 270 if (w == NULL) { 271 return; 272 } 273 274 spdk_json_write_name(w, "error"); 275 spdk_json_write_object_begin(w); 276 spdk_json_write_name(w, "code"); 277 spdk_json_write_int32(w, error_code); 278 spdk_json_write_name(w, "message"); 279 spdk_json_write_string(w, msg); 280 spdk_json_write_object_end(w); 281 282 end_response(conn, w); 283 } 284 285 SPDK_LOG_REGISTER_TRACE_FLAG("rpc", SPDK_TRACE_RPC) 286