예제 #1
0
static int send_error(struct jrpc_connection *conn, int code, char *message,
		      struct json *id)
{
	int return_value = 0;
	struct json *result_root = json_create_object();
	struct json *error_root = json_create_object();
	json_add_number_to_object(error_root, "code", code);
	json_add_string_to_object(error_root, "message", message);
	json_add_item_to_object(result_root, "error", error_root);
	json_add_item_to_object(result_root, "id", id);
	return_value = send_response(conn,
			json_to_string_unformatted(result_root));
	json_delete(result_root);
	free(message);
	return return_value;
}
예제 #2
0
파일: server.c 프로젝트: yubo/libubox
static struct json *foo(struct jrpc_context * ctx, struct json *params,
			      struct json *id)
{
	struct json *reply, *item, *array;
	int a, b, i;
	char buf[1024];

	json_dump(params);
	json_dump(id);

	item = json_get_object_item(params->child, "A");
	a = item->valueint;

	item = json_get_object_item(params->child, "B");
	b = item->valueint;

	sprintf(buf, "recv a:%d b:%d", a, b);

	array = json_create_array();

	for(i = 0; i < a; i ++){
		item = json_create_object();
		json_add_number_to_object(item, "A", i);
		json_add_number_to_object(item, "B", b++);
		json_add_item_to_array(array, item);
	}




	reply = json_create_object();
	json_add_item_to_object(reply, "Args", array);
	json_add_string_to_object(reply, "Str", buf);
	json_dump(reply);

	return reply;
}
예제 #3
0
int jrpc_client_call(struct jrpc_client *client, const char *method,
		     struct json *params, struct json **response)
{
	int fd, max_read_size;
	size_t bytes_read = 0;
	char *new_buffer, *end_ptr = NULL;
	struct jrpc_connection *conn;
	struct json *root, *request;

	request = json_create_object();
	json_add_string_to_object(request, "method", method);
	json_add_item_to_object(request, "params", params);
	json_add_number_to_object(request, "id", client->id);

	send_request(&client->conn, json_to_string(request));
	json_delete(request);

	// read
	conn = &client->conn;
	fd = conn->sock.fd;

	for (;;) {
		if (conn->pos == (conn->buffer_size - 1)) {
			conn->buffer_size *= 2;
			new_buffer = realloc(conn->buffer, conn->buffer_size);
			if (new_buffer == NULL) {
				perror("Memory error");
				return -ENOMEM;
			}
			conn->buffer = new_buffer;
			memset(conn->buffer + conn->pos, 0,
			       conn->buffer_size - conn->pos);
		}
		// can not fill the entire buffer, string must be NULL terminated
		max_read_size = conn->buffer_size - conn->pos - 1;
		if ((bytes_read =
		     read(fd, conn->buffer + conn->pos, max_read_size))
		    == -1) {
			elog("read %d\n", strerror(errno));
			return -EIO;
		}
		if (!bytes_read) {
			// client closed the sending half of the connection
			if (client->conn.debug_level)
				dlog("Client closed connection.\n");
			return -EIO;
		}

		conn->pos += bytes_read;

		if ((root = json_parse_stream(conn->buffer, &end_ptr)) != NULL) {
			if (client->conn.debug_level > 1) {
				dlog("Valid JSON Received:\n%s\n",
				       json_to_string(root));
			}

			if (root->type == JSON_T_OBJECT) {
				struct json *id =
				    json_get_object_item(root, "id");

				if (id->type == JSON_T_STRING) {
					if (client->id != atoi(id->string))
						goto out;
				} else if (id->type == JSON_T_NUMBER) {
					if (client->id != id->valueint)
						goto out;
				}
				client->id++;
				//shift processed request, discarding it
				memmove(conn->buffer, end_ptr,
					strlen(end_ptr) + 2);
				conn->pos = strlen(end_ptr);
				memset(conn->buffer + conn->pos, 0,
				       conn->buffer_size - conn->pos - 1);

				*response =
				    json_detach_item_from_object(root,
								 "result");
				if (*response == NULL)
					goto out;

				json_delete(root);
				return 0;
			}
out:
			elog("INVALID JSON Received:\n---\n%s\n---\n",
			       conn->buffer);
			json_delete(root);
			return -EINVAL;
		} else if (end_ptr != (conn->buffer + conn->pos)) {
			// did we parse the all buffer? If so, just wait for more.
			// else there was an error before the buffer's end
			if (client->conn.debug_level) {
				elog("INVALID JSON Received:\n---\n%s\n---\n",
				       conn->buffer);
			}
			send_error(conn, JRPC_PARSE_ERROR,
				   strdup("Parse error. Invalid JSON"
					  " was received by the client."),
				   NULL);
			return -EINVAL;
		}
	}
}