avoid wasting resources on failed writes...

This commit is contained in:
Roberto De Ioris
2013-01-20 14:45:40 +01:00
parent c9987aa721
commit 70d9dab5ef
+21 -9
View File
@@ -5,7 +5,7 @@ extern struct uwsgi_server uwsgi;
// status could be NNN or NNN message
int uwsgi_response_prepare_headers(struct wsgi_request *wsgi_req, char *status, uint16_t status_len) {
if (wsgi_req->headers_sent || wsgi_req->headers_size || wsgi_req->response_size || status_len < 3) return -1;
if (wsgi_req->headers_sent || wsgi_req->headers_size || wsgi_req->response_size || status_len < 3 || wsgi_req->write_errors) return -1;
if (!wsgi_req->headers) {
wsgi_req->headers = uwsgi_buffer_new(uwsgi.page_size);
@@ -15,20 +15,21 @@ int uwsgi_response_prepare_headers(struct wsgi_request *wsgi_req, char *status,
// reset the buffer (could be useful for rollbacks...)
wsgi_req->headers->pos = 0;
struct uwsgi_buffer *hh = wsgi_req->socket->proto_prepare_headers(wsgi_req, status, status_len);
if (!hh) return -1;
if (!hh) {wsgi_req->write_errors++; return -1;}
if (uwsgi_buffer_append(wsgi_req->headers, hh->buf, hh->pos)) goto error;
uwsgi_buffer_destroy(hh);
wsgi_req->status = uwsgi_str3_num(status);
return 0;
error:
uwsgi_buffer_destroy(hh);
wsgi_req->write_errors++;
return -1;
}
//each protocol has its header generator
int uwsgi_response_add_header(struct wsgi_request *wsgi_req, char *key, uint16_t key_len, char *value, uint16_t value_len) {
if (wsgi_req->headers_sent || wsgi_req->headers_size || wsgi_req->response_size) return -1;
if (wsgi_req->headers_sent || wsgi_req->headers_size || wsgi_req->response_size || wsgi_req->write_errors) return -1;
if (!wsgi_req->headers) {
wsgi_req->headers = uwsgi_buffer_new(uwsgi.page_size);
@@ -36,18 +37,19 @@ int uwsgi_response_add_header(struct wsgi_request *wsgi_req, char *key, uint16_t
}
struct uwsgi_buffer *hh = wsgi_req->socket->proto_add_header(wsgi_req, key, key_len, value, value_len);
if (!hh) return -1;
if (!hh) { wsgi_req->write_errors++ ; return -1;}
if (uwsgi_buffer_append(wsgi_req->headers, hh->buf, hh->pos)) goto error;
wsgi_req->header_cnt++;
uwsgi_buffer_destroy(hh);
return 0;
error:
uwsgi_buffer_destroy(hh);
wsgi_req->write_errors++;
return -1;
}
int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) {
if (wsgi_req->headers_sent || !wsgi_req->headers || wsgi_req->response_size) {
if (wsgi_req->headers_sent || !wsgi_req->headers || wsgi_req->response_size || wsgi_req->write_errors) {
return UWSGI_OK;
}
@@ -64,7 +66,7 @@ int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) {
}
if (wsgi_req->socket->proto_fix_headers(wsgi_req)) return -1;
if (wsgi_req->socket->proto_fix_headers(wsgi_req)) { wsgi_req->write_errors++ ; return -1;}
for(;;) {
int ret = wsgi_req->socket->proto_write_headers(wsgi_req, wsgi_req->headers->buf, wsgi_req->headers->pos);
@@ -72,13 +74,14 @@ int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) {
if (!uwsgi.ignore_write_errors) {
uwsgi_error("uwsgi_response_write_headers_do()");
}
wsgi_req->write_errors++;
return -1;
}
if (ret == UWSGI_OK) {
break;
}
ret = uwsgi.wait_write_hook(wsgi_req);
if (ret < 0) return -1;
if (ret < 0) { wsgi_req->write_errors++; return -1;}
// callback based hook...
if (ret == UWSGI_AGAIN) return UWSGI_AGAIN;
}
@@ -92,10 +95,13 @@ int uwsgi_response_write_headers_do(struct wsgi_request *wsgi_req) {
int uwsgi_response_write_body_do(struct wsgi_request *wsgi_req, char *buf, size_t len) {
if (wsgi_req->write_errors) return -1;
if (!wsgi_req->headers_sent) {
int ret = uwsgi_response_write_headers_do(wsgi_req);
if (ret == UWSGI_OK) goto sendbody;
if (ret == UWSGI_AGAIN) return UWSGI_AGAIN;
wsgi_req->write_errors++;
return -1;
}
@@ -109,13 +115,14 @@ sendbody:
if (!uwsgi.ignore_write_errors) {
uwsgi_error("uwsgi_response_write_body_do()");
}
wsgi_req->write_errors++;
return -1;
}
if (ret == UWSGI_OK) {
break;
}
ret = uwsgi.wait_write_hook(wsgi_req);
if (ret < 0) return -1;
if (ret < 0) { wsgi_req->write_errors++; return -1;}
// callback based hook...
if (ret == UWSGI_AGAIN) return UWSGI_AGAIN;
}
@@ -129,10 +136,13 @@ sendbody:
int uwsgi_response_sendfile_do(struct wsgi_request *wsgi_req, int fd, size_t pos, size_t len) {
if (wsgi_req->write_errors) return -1;
if (!wsgi_req->headers_sent) {
int ret = uwsgi_response_write_headers_do(wsgi_req);
if (ret == UWSGI_OK) goto sendfile;
if (ret == UWSGI_AGAIN) return UWSGI_AGAIN;
wsgi_req->write_errors++;
return -1;
}
@@ -142,6 +152,7 @@ sendfile:
struct stat st;
if (fstat(fd, &st)) {
uwsgi_error("fstat()");
wsgi_req->write_errors++;
return -1;
}
len = st.st_size;
@@ -153,13 +164,14 @@ sendfile:
if (!uwsgi.ignore_write_errors) {
uwsgi_error("uwsgi_response_sendfile_do()");
}
wsgi_req->write_errors++;
return -1;
}
if (ret == UWSGI_OK) {
break;
}
ret = uwsgi.wait_write_hook(wsgi_req);
if (ret < 0) return -1;
if (ret < 0) { wsgi_req->write_errors++; return -1;}
// callback based hook...
if (ret == UWSGI_AGAIN) return UWSGI_AGAIN;
}