static void connection_cb(struct uloop_fd *sock, unsigned int events) { struct json *root; int fd, max_read_size; struct jrpc_connection *conn; struct jrpc_server *server; ssize_t bytes_read = 0; char *new_buffer, *end_ptr = NULL; conn = container_of(sock, struct jrpc_connection, sock); fd = sock->fd; server = conn->server; if (conn->pos == (conn->buffer_size - 1)) { conn->buffer_size *= 2; new_buffer = realloc(conn->buffer, conn->buffer_size); if (new_buffer == NULL) { elog("Memory error %s\n", strerror(errno)); return close_connection(sock); } 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; do { bytes_read = read(fd, conn->buffer + conn->pos, max_read_size); if (bytes_read < 0) { if (errno == EINVAL) continue; if (errno == EAGAIN) break; // error return close_connection(sock); } if (bytes_read == 0) { // client closed the sending half of the connection if (server->debug_level) dlog("Client closed connection.\n"); return close_connection(sock); } break; } while (1); conn->pos += bytes_read; if ((root = json_parse_stream(conn->buffer, &end_ptr)) != NULL) { if (server->debug_level > 1) { dlog("Valid JSON Received:\n%s\n", json_to_string(root)); } if (root->type == JSON_T_OBJECT) { eval_request(server, conn, root); } //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); json_delete(root); } else { // did we parse the all buffer? If so, just wait for more. // else there was an error before the buffer's end if (end_ptr != (conn->buffer + conn->pos)) { if (server->debug_level) { dlog("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 server."), NULL); return close_connection(sock); } } }
static void connection_cb(struct ev_loop *loop, ev_io *w, int revents) { struct jrpc_connection *conn; struct jrpc_server *server = (struct jrpc_server *) w->data; size_t bytes_read = 0; //get our 'subclassed' event watcher conn = (struct jrpc_connection *) w; int fd = conn->fd; if (conn->pos == (conn->buffer_size - 1)) { char * new_buffer = realloc(conn->buffer, conn->buffer_size *= 2); if (new_buffer == NULL) { perror("Memory error"); return close_connection(loop, w); } 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 int max_read_size = conn->buffer_size - conn->pos - 1; if ((bytes_read = read(fd, conn->buffer + conn->pos, max_read_size)) == -1) { perror("read"); return close_connection(loop, w); } if (!bytes_read) { // client closed the sending half of the connection if (server->debug_level) printf("Client closed connection.\n"); return close_connection(loop, w); } else { cJSON *root; char *end_ptr = NULL; conn->pos += bytes_read; if ((root = cJSON_Parse_Stream(conn->buffer, &end_ptr)) != NULL) { if (server->debug_level > 1) { char * str_result = cJSON_Print(root); printf("Valid JSON Received:\n%s\n", str_result); free(str_result); } if (root->type == cJSON_Object) { eval_request(server, conn, root); } //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); cJSON_Delete(root); } else { // did we parse the all buffer? If so, just wait for more. // else there was an error before the buffer's end if (end_ptr != (conn->buffer + conn->pos)) { if (server->debug_level) { printf("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 server."), NULL); return close_connection(loop, w); } } } }