Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
static int eval_request(struct jrpc_server *server,
			struct jrpc_connection *conn, struct json *root)
{
	struct json *method, *params, *id;
	method = json_get_object_item(root, "method");

	if (method != NULL && method->type == JSON_T_STRING) {
		params = json_get_object_item(root, "params");
		if (params == NULL || params->type == JSON_T_ARRAY
		    || params->type == JSON_T_OBJECT) {
			id = json_get_object_item(root, "id");
			if (id == NULL || id->type == JSON_T_STRING
			    || id->type == JSON_T_NUMBER) {
				return invoke_procedure_id(server, method, conn,
							   id, params);
			}

		}
	}
	send_error(conn, JRPC_INVALID_REQUEST,
		   strdup("The JSON sent is not a valid Request object."),
		   NULL);
	return -1;
}
Ejemplo n.º 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;
		}
	}
}