int reqs_read_post(struct reqs_t *reqs) { char *post_data; int size_recv; int post_size = reqs->content_length; if (post_size == 0) { reqs->post_read_flag = 1; return 1; } if (reqs->post_read_flag) { return 1; } if (post_size > reqs->htdx->max_post_size || post_size < 0) { set_keep_alive(reqs, 0); reqs_throw_status(reqs, 400, "post data too large!"); return 0; } post_data = calloc(post_size + 1, sizeof(char)); size_recv = conn_recv(reqs->conn, post_data, post_size); if (size_recv != post_size) { free(post_data); set_keep_alive(reqs, 0); reqs_throw_status(reqs, 500, "read post data error!"); chtd_cry(reqs->htdx, "recv post data error [%d]", size_recv); return 0; } reqs->post_size = post_size; reqs->post_data = post_data; reqs->post_read_flag = 1; return 1; }
void reqs_skip_post(struct reqs_t *reqs) { char static buff[1024]; int size = reqs->content_length; while (size) { size -= conn_recv(reqs->conn, buff, size > 1024 ? 1024 : size); } reqs->post_read_flag = 1; }
static rstatus_t core_recv(struct context *ctx, struct conn *conn) { rstatus_t status; status = conn_recv(ctx, conn); if (status != DN_OK) { log_info("recv on %s %d failed: %s", conn_get_type_string(conn), conn->sd, strerror(errno)); } return status; }
rstatus_t call_recv(struct context *ctx, struct call *call) { rstatus_t status; struct conn *conn = call->conn; ssize_t n; size_t rcvd; if (call->rsp.rsize == 0) { size_t chunk_size; ASSERT(call->rsp.rcurr > call->rsp.pcurr); /* * Make space in the read buffer by moving the unparsed chunk * at the tail end to the head. */ chunk_size = (size_t)(call->rsp.rcurr - call->rsp.pcurr); mcp_memmove(conn->buf, call->rsp.pcurr, chunk_size); call->rsp.pcurr = conn->buf; call->rsp.rcurr = conn->buf + chunk_size; call->rsp.rsize = sizeof(conn->buf) - chunk_size; } if (call->rsp.rcvd == 0) { ecb_signal(ctx, EVENT_CALL_RECV_START, call); } n = conn_recv(conn, call->rsp.rcurr, call->rsp.rsize); rcvd = n > 0 ? (size_t)n : 0; call->rsp.rcvd += rcvd; call->rsp.rcurr += rcvd; call->rsp.rsize -= rcvd; if (n <= 0) { if (n == 0 || n == MCP_EAGAIN) { return MCP_OK; } return MCP_ERROR; } do { struct call *next_call; /* next call in recv q */ status = call_parse_rsp(ctx, call); if (status != MCP_OK) { if (status == MCP_EAGAIN) { /* incomplete response; parse again when more data arrives */ return MCP_OK; } return status; } next_call = NULL; /* * Spill over unparsed response onto the next call and update * the current call appropriately */ if (call->rsp.rcurr != call->rsp.pcurr) { next_call = STAILQ_NEXT(call, call_tqe); if (next_call == NULL) { log_debug(LOG_ERR, "stray response type %d on c %"PRIu64"", call->rsp.type, conn->id); conn->err = EINVAL; return MCP_ERROR; } ecb_signal(ctx, EVENT_CALL_RECV_START, next_call); next_call->rsp.rcurr = call->rsp.rcurr; next_call->rsp.rsize = call->rsp.rsize; next_call->rsp.pcurr = call->rsp.pcurr; /* * Calculate the exact bytes received on this call and accumulate * the remaining bytes onto the next call */ ASSERT(call->rsp.rcurr > call->rsp.pcurr); next_call->rsp.rcvd = (size_t)(call->rsp.rcurr - call->rsp.pcurr); call->rsp.rcvd -= next_call->rsp.rcvd; } conn->ncall_recvq--; STAILQ_REMOVE(&conn->call_recvq, call, call, call_tqe); call_reset_timer(ctx, call); ecb_signal(ctx, EVENT_CALL_RECV_STOP, call); ecb_signal(ctx, EVENT_CALL_DESTROYED, call); call_put(call); call = next_call; } while (call != NULL); return MCP_OK; }