int uwsgi_postbuffer_do_in_mem(struct wsgi_request *wsgi_req) { size_t remains = wsgi_req->post_cl; int ret; char *ptr = wsgi_req->post_buffering_buf; while (remains > 0) { if (uwsgi.harakiri_options.workers > 0) { inc_harakiri(wsgi_req, uwsgi.harakiri_options.workers); } ssize_t rlen = wsgi_req->socket->proto_read_body(wsgi_req, ptr, remains); if (rlen > 0) { remains -= rlen; ptr += rlen; continue; } if (rlen == 0) { uwsgi_read_error0(remains); return -1; } if (rlen < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { goto wait; } uwsgi_read_error(remains); wsgi_req->read_errors++; return -1; } wait: ret = uwsgi_wait_read_req(wsgi_req); if (ret > 0) { rlen = wsgi_req->socket->proto_read_body(wsgi_req, ptr, remains); if (rlen > 0) { remains -= rlen; ptr += rlen; continue; } } if (ret < 0) { uwsgi_read_error(remains); wsgi_req->read_errors++; return -1; } uwsgi_read_timeout(remains); return -1; } return 0; }
int uwsgi_postbuffer_do_in_disk(struct wsgi_request *wsgi_req) { size_t post_remains = wsgi_req->post_cl; int ret; int upload_progress_fd = -1; char *upload_progress_filename = NULL; wsgi_req->post_file = tmpfile(); if (!wsgi_req->post_file) { uwsgi_error("uwsgi_postbuffer_do_in_disk()/tmpfile()"); return -1; } if (uwsgi.upload_progress) { // first check for X-Progress-ID size // separator + 'X-Progress-ID' + '=' + uuid upload_progress_filename = uwsgi_upload_progress_create(wsgi_req, &upload_progress_fd); if (!upload_progress_filename) { uwsgi_log("invalid X-Progress-ID value: must be a UUID\n"); } } // manage buffered data and upload progress while (post_remains > 0) { // during post buffering we need to constantly reset the harakiri if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) { inc_harakiri(uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); } // we use the already available post buffering buffer to read chunks.... size_t remains = UMIN(post_remains, uwsgi.post_buffering); // first try to read data (there could be something already available ssize_t rlen = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_buffering_buf, remains); if (rlen > 0) goto write; if (rlen == 0) { uwsgi_read_error0(remains); goto end; } if (rlen < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { goto wait; } uwsgi_read_error(remains); goto end; } wait: ret = uwsgi_wait_read_req(wsgi_req); if (ret > 0) { rlen = wsgi_req->socket->proto_read_body(wsgi_req, wsgi_req->post_buffering_buf, remains); if (rlen > 0) goto write; if (rlen == 0) { uwsgi_read_error0(remains); } else { uwsgi_read_error(remains); } goto end; } if (ret < 0) { uwsgi_read_error(remains); goto end; } uwsgi_read_timeout(remains); goto end; write: if (fwrite(wsgi_req->post_buffering_buf, rlen, 1, wsgi_req->post_file) != 1) { uwsgi_error("uwsgi_postbuffer_do_in_disk()/fwrite()"); goto end; } post_remains -= rlen; if (upload_progress_filename) { // stop updating it on errors if (uwsgi_upload_progress_update(wsgi_req, upload_progress_fd, post_remains)) { uwsgi_upload_progress_destroy(upload_progress_filename, upload_progress_fd); upload_progress_filename = NULL; } } } rewind(wsgi_req->post_file); if (upload_progress_filename) { uwsgi_upload_progress_destroy(upload_progress_filename, upload_progress_fd); } return 0; end: if (upload_progress_filename) { uwsgi_upload_progress_destroy(upload_progress_filename, upload_progress_fd); } return -1; }