summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstbuehler <stbuehler@152afb58-edef-0310-8abb-c4023f1b3aa9>2015-08-22 17:04:02 +0000
committerstbuehler <stbuehler@152afb58-edef-0310-8abb-c4023f1b3aa9>2015-08-22 17:04:02 +0000
commitcc4bb35b2616648070f423d1dc457600eb6cfce3 (patch)
tree1f8ffedc79a98e14e8e5ee94075dcb6f2f7e2013
parent601c8d593f18679bc6c3dd987e27374b26012588 (diff)
downloadlighttpd-cc4bb35b2616648070f423d1dc457600eb6cfce3.tar.gz
maintain cq->bytes_in in chunk API; keep bytes_out/bytes_in synced
From: Stefan Bühler <stbuehler@web.de> git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3016 152afb58-edef-0310-8abb-c4023f1b3aa9
-rw-r--r--src/chunk.c170
-rw-r--r--src/connections.c1
-rw-r--r--src/mod_cgi.c43
-rw-r--r--src/mod_fastcgi.c19
-rw-r--r--src/mod_proxy.c1
-rw-r--r--src/mod_scgi.c1
-rw-r--r--src/mod_webdav.c12
7 files changed, 97 insertions, 150 deletions
diff --git a/src/chunk.c b/src/chunk.c
index fef61259..1a9b421f 100644
--- a/src/chunk.c
+++ b/src/chunk.c
@@ -91,6 +91,23 @@ static void chunk_free(chunk *c) {
free(c);
}
+static off_t chunk_remaining_length(const chunk *c) {
+ off_t len = 0;
+ switch (c->type) {
+ case MEM_CHUNK:
+ len = buffer_string_length(c->mem);
+ break;
+ case FILE_CHUNK:
+ len = c->file.length;
+ break;
+ default:
+ force_assert(c->type == MEM_CHUNK || c->type == FILE_CHUNK);
+ break;
+ }
+ force_assert(c->offset <= len);
+ return len - c->offset;
+}
+
void chunkqueue_free(chunkqueue *cq) {
chunk *c, *pc;
@@ -151,6 +168,7 @@ static void chunkqueue_prepend_chunk(chunkqueue *cq, chunk *c) {
if (NULL == cq->last) {
cq->last = c;
}
+ cq->bytes_in += chunk_remaining_length(c);
}
static void chunkqueue_append_chunk(chunkqueue *cq, chunk *c) {
@@ -162,6 +180,7 @@ static void chunkqueue_append_chunk(chunkqueue *cq, chunk *c) {
if (NULL == cq->first) {
cq->first = c;
}
+ cq->bytes_in += chunk_remaining_length(c);
}
void chunkqueue_reset(chunkqueue *cq) {
@@ -304,6 +323,7 @@ void chunkqueue_use_memory(chunkqueue *cq, size_t len) {
if (len > 0) {
buffer_commit(b, len);
+ cq->bytes_in += len;
} else if (buffer_string_is_empty(b)) {
/* unused buffer: can't remove chunk easily from
* end of list, so just reset the buffer
@@ -324,22 +344,7 @@ void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) {
if (NULL == c) break;
- switch (c->type) {
- case MEM_CHUNK:
- clen = buffer_string_length(c->mem);
- break;
- case FILE_CHUNK:
- clen = c->file.length;
- break;
- }
- force_assert(clen >= c->offset);
- clen -= c->offset;
- use = len >= clen ? clen : len;
-
- src->bytes_out += use;
- dest->bytes_in += use;
- len -= use;
-
+ clen = chunk_remaining_length(c);
if (0 == clen) {
/* drop empty chunk */
src->first = c->next;
@@ -348,29 +353,33 @@ void chunkqueue_steal(chunkqueue *dest, chunkqueue *src, off_t len) {
continue;
}
+ use = len >= clen ? clen : len;
+ len -= use;
+
if (use == clen) {
/* move complete chunk */
src->first = c->next;
if (c == src->last) src->last = NULL;
chunkqueue_append_chunk(dest, c);
- continue;
- }
-
- /* partial chunk with length "use" */
+ } else {
+ /* partial chunk with length "use" */
+
+ switch (c->type) {
+ case MEM_CHUNK:
+ chunkqueue_append_mem(dest, c->mem->ptr + c->offset, use);
+ break;
+ case FILE_CHUNK:
+ /* tempfile flag is in "last" chunk after the split */
+ chunkqueue_append_file(dest, c->file.name, c->file.start + c->offset, use);
+ break;
+ }
- switch (c->type) {
- case MEM_CHUNK:
- chunkqueue_append_mem(dest, c->mem->ptr + c->offset, use);
- break;
- case FILE_CHUNK:
- /* tempfile flag is in "last" chunk after the split */
- chunkqueue_append_file(dest, c->file.name, c->file.start + c->offset, use);
- break;
+ c->offset += use;
+ force_assert(0 == len);
}
- c->offset += use;
- force_assert(0 == len);
+ src->bytes_out += use;
}
}
@@ -479,6 +488,7 @@ static int chunkqueue_append_to_tempfile(server *srv, chunkqueue *dest, const ch
}
dst_c->file.length += len;
+ dest->bytes_in += len;
return 0;
}
@@ -490,22 +500,7 @@ int chunkqueue_steal_with_tempfiles(server *srv, chunkqueue *dest, chunkqueue *s
if (NULL == c) break;
- switch (c->type) {
- case MEM_CHUNK:
- clen = buffer_string_length(c->mem);
- break;
- case FILE_CHUNK:
- clen = c->file.length;
- break;
- }
- force_assert(clen >= c->offset);
- clen -= c->offset;
- use = len >= clen ? clen : len;
-
- src->bytes_out += use;
- dest->bytes_in += use;
- len -= use;
-
+ clen = chunk_remaining_length(c);
if (0 == clen) {
/* drop empty chunk */
src->first = c->next;
@@ -514,12 +509,15 @@ int chunkqueue_steal_with_tempfiles(server *srv, chunkqueue *dest, chunkqueue *s
continue;
}
- if (FILE_CHUNK == c->type) {
+ use = (len >= clen) ? clen : len;
+ len -= use;
+
+ switch (c->type) {
+ case FILE_CHUNK:
if (use == clen) {
/* move complete chunk */
src->first = c->next;
if (c == src->last) src->last = NULL;
-
chunkqueue_append_chunk(dest, c);
} else {
/* partial chunk with length "use" */
@@ -529,25 +527,28 @@ int chunkqueue_steal_with_tempfiles(server *srv, chunkqueue *dest, chunkqueue *s
c->offset += use;
force_assert(0 == len);
}
- continue;
- }
-
- /* store "use" bytes from memory chunk in tempfile */
- if (0 != chunkqueue_append_to_tempfile(srv, dest, c->mem->ptr + c->offset, use)) {
- /* undo counters */
- src->bytes_out -= use;
- dest->bytes_in -= use;
- return -1;
- }
+ break;
+ case MEM_CHUNK:
+ /* store "use" bytes from memory chunk in tempfile */
+ if (0 != chunkqueue_append_to_tempfile(srv, dest, c->mem->ptr + c->offset, use)) {
+ return -1;
+ }
- c->offset += use;
- if (use == clen) {
- /* finished chunk */
- src->first = c->next;
- if (c == src->last) src->last = NULL;
- chunkqueue_push_unused_chunk(src, c);
+ if (use == clen) {
+ /* finished chunk */
+ src->first = c->next;
+ if (c == src->last) src->last = NULL;
+ chunkqueue_push_unused_chunk(src, c);
+ } else {
+ /* partial chunk */
+ c->offset += use;
+ force_assert(0 == len);
+ }
+ break;
}
+
+ src->bytes_out += use;
}
return 0;
@@ -558,18 +559,7 @@ off_t chunkqueue_length(chunkqueue *cq) {
chunk *c;
for (c = cq->first; c; c = c->next) {
- off_t c_len = 0;
-
- switch (c->type) {
- case MEM_CHUNK:
- c_len = buffer_string_length(c->mem);
- break;
- case FILE_CHUNK:
- c_len = c->file.length;
- break;
- }
- force_assert(c_len >= c->offset);
- len += c_len - c->offset;
+ len += chunk_remaining_length(c);
}
return len;
@@ -582,20 +572,10 @@ int chunkqueue_is_empty(chunkqueue *cq) {
void chunkqueue_mark_written(chunkqueue *cq, off_t len) {
off_t written = len;
chunk *c;
+ force_assert(len >= 0);
for (c = cq->first; NULL != c; c = cq->first) {
- off_t c_len = 0;
-
- switch (c->type) {
- case MEM_CHUNK:
- c_len = buffer_string_length(c->mem);
- break;
- case FILE_CHUNK:
- c_len = c->file.length;
- break;
- }
- force_assert(c_len >= c->offset);
- c_len -= c->offset;
+ off_t c_len = chunk_remaining_length(c);
if (0 == written && 0 != c_len) break; /* no more finished chunks */
@@ -622,19 +602,7 @@ void chunkqueue_remove_finished_chunks(chunkqueue *cq) {
chunk *c;
for (c = cq->first; c; c = cq->first) {
- off_t c_len = 0;
-
- switch (c->type) {
- case MEM_CHUNK:
- c_len = buffer_string_length(c->mem);
- break;
- case FILE_CHUNK:
- c_len = c->file.length;
- break;
- }
- force_assert(c_len >= c->offset);
-
- if (c_len > c->offset) break; /* not finished yet */
+ if (0 != chunk_remaining_length(c)) break; /* not finished yet */
cq->first = c->next;
if (c == cq->last) cq->last = NULL;
diff --git a/src/connections.c b/src/connections.c
index e01700a1..7e205aff 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -967,6 +967,7 @@ found_header_end:
buffer_append_string_len(con->request.request, c->mem->ptr + c->offset, len);
c->offset += len;
+ cq->bytes_out += len;
if (c == last_chunk) break;
}
diff --git a/src/mod_cgi.c b/src/mod_cgi.c
index 01b1877a..545bcc94 100644
--- a/src/mod_cgi.c
+++ b/src/mod_cgi.c
@@ -814,11 +814,12 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
cgi_env_add(&env, CONST_STR_LEN("SERVER_NAME"), con->server_name->ptr, len);
} else {
#ifdef HAVE_IPV6
- s = inet_ntop(srv_sock->addr.plain.sa_family,
- srv_sock->addr.plain.sa_family == AF_INET6 ?
- (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
- (const void *) &(srv_sock->addr.ipv4.sin_addr),
- b2, sizeof(b2)-1);
+ s = inet_ntop(
+ srv_sock->addr.plain.sa_family,
+ srv_sock->addr.plain.sa_family == AF_INET6 ?
+ (const void *) &(srv_sock->addr.ipv6.sin6_addr) :
+ (const void *) &(srv_sock->addr.ipv4.sin_addr),
+ b2, sizeof(b2)-1);
#else
s = inet_ntoa(srv_sock->addr.ipv4.sin_addr);
#endif
@@ -842,14 +843,16 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
switch (srv_sock->addr.plain.sa_family) {
#ifdef HAVE_IPV6
case AF_INET6:
- s = inet_ntop(srv_sock->addr.plain.sa_family,
- (const void *) &(srv_sock->addr.ipv6.sin6_addr),
- b2, sizeof(b2)-1);
+ s = inet_ntop(
+ srv_sock->addr.plain.sa_family,
+ (const void *) &(srv_sock->addr.ipv6.sin6_addr),
+ b2, sizeof(b2)-1);
break;
case AF_INET:
- s = inet_ntop(srv_sock->addr.plain.sa_family,
- (const void *) &(srv_sock->addr.ipv4.sin_addr),
- b2, sizeof(b2)-1);
+ s = inet_ntop(
+ srv_sock->addr.plain.sa_family,
+ (const void *) &(srv_sock->addr.ipv4.sin_addr),
+ b2, sizeof(b2)-1);
break;
#else
case AF_INET:
@@ -880,14 +883,16 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
switch (con->dst_addr.plain.sa_family) {
#ifdef HAVE_IPV6
case AF_INET6:
- s = inet_ntop(con->dst_addr.plain.sa_family,
- (const void *) &(con->dst_addr.ipv6.sin6_addr),
- b2, sizeof(b2)-1);
+ s = inet_ntop(
+ con->dst_addr.plain.sa_family,
+ (const void *) &(con->dst_addr.ipv6.sin6_addr),
+ b2, sizeof(b2)-1);
break;
case AF_INET:
- s = inet_ntop(con->dst_addr.plain.sa_family,
- (const void *) &(con->dst_addr.ipv4.sin_addr),
- b2, sizeof(b2)-1);
+ s = inet_ntop(
+ con->dst_addr.plain.sa_family,
+ (const void *) &(con->dst_addr.ipv4.sin_addr),
+ b2, sizeof(b2)-1);
break;
#else
case AF_INET:
@@ -1088,14 +1093,12 @@ static int cgi_create_env(server *srv, connection *con, plugin_data *p, buffer *
}
if (r > 0) {
- c->offset += r;
- cq->bytes_out += r;
+ chunkqueue_mark_written(cq, r);
} else {
log_error_write(srv, __FILE__, __LINE__, "ss", "write() failed due to: ", strerror(errno));
con->http_status = 500;
break;
}
- chunkqueue_remove_finished_chunks(cq);
}
}
diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c
index 14d5a21e..f70a411f 100644
--- a/src/mod_fastcgi.c
+++ b/src/mod_fastcgi.c
@@ -2022,7 +2022,6 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
fcgi_header(&(header), FCGI_PARAMS, request_id, 0, 0);
buffer_append_string_len(b, (const char *)&header, sizeof(header));
- hctx->wb->bytes_in += buffer_string_length(b);
chunkqueue_append_buffer(hctx->wb, b);
buffer_free(b);
}
@@ -2041,7 +2040,6 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
fcgi_header(&(header), FCGI_STDIN, request_id, weWant, 0);
chunkqueue_append_mem(hctx->wb, (const char *)&header, sizeof(header));
- hctx->wb->bytes_in += sizeof(header);
if (p->conf.debug > 10) {
log_error_write(srv, __FILE__, __LINE__, "soso", "tosend:", offset, "/", req_cq->bytes_in);
@@ -2057,8 +2055,6 @@ static int fcgi_create_env(server *srv, handler_ctx *hctx, size_t request_id) {
fcgi_header(&(header), FCGI_STDIN, request_id, 0, 0);
chunkqueue_append_mem(hctx->wb, (const char *)&header, sizeof(header));
- hctx->wb->bytes_in += sizeof(header);
-
return 0;
}
@@ -2349,20 +2345,7 @@ static int fastcgi_get_packet(server *srv, handler_ctx *hctx, fastcgi_response_p
buffer_string_set_length(packet->b, buffer_string_length(packet->b) - packet->padding);
}
- /* tag the chunks as read */
- toread = packet->len + sizeof(FCGI_Header);
- for (c = hctx->rb->first; c && toread; c = c->next) {
- if (buffer_string_length(c->mem) - c->offset <= toread) {
- /* we read this whole buffer, move it to unused */
- toread -= buffer_string_length(c->mem) - c->offset;
- c->offset = buffer_string_length(c->mem); /* everthing has been written */
- } else {
- c->offset += toread;
- toread = 0;
- }
- }
-
- chunkqueue_remove_finished_chunks(hctx->rb);
+ chunkqueue_mark_written(hctx->rb, packet->len + sizeof(FCGI_Header));
return 0;
}
diff --git a/src/mod_proxy.c b/src/mod_proxy.c
index 79ec6ee2..d5d37ca3 100644
--- a/src/mod_proxy.c
+++ b/src/mod_proxy.c
@@ -496,7 +496,6 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
- hctx->wb->bytes_in += buffer_string_length(b);
chunkqueue_append_buffer(hctx->wb, b);
buffer_free(b);
diff --git a/src/mod_scgi.c b/src/mod_scgi.c
index 733b51ce..cb1e9c3e 100644
--- a/src/mod_scgi.c
+++ b/src/mod_scgi.c
@@ -1611,7 +1611,6 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
buffer_append_string_buffer(b, p->scgi_env);
buffer_append_string_len(b, CONST_STR_LEN(","));
- hctx->wb->bytes_in += buffer_string_length(b);
chunkqueue_append_buffer(hctx->wb, b);
buffer_free(b);
diff --git a/src/mod_webdav.c b/src/mod_webdav.c
index 2fff8c33..2c1fe87c 100644
--- a/src/mod_webdav.c
+++ b/src/mod_webdav.c
@@ -1033,8 +1033,7 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
log_error_write(srv, __FILE__, __LINE__, "sodd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
}
- c->offset += weHave;
- cq->bytes_out += weHave;
+ chunkqueue_mark_written(cq, weHave);
break;
case MEM_CHUNK:
@@ -1051,15 +1050,12 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
log_error_write(srv, __FILE__, __LINE__, "sodd", "xmlParseChunk failed at:", cq->bytes_out, weHave, err);
}
- c->offset += weHave;
- cq->bytes_out += weHave;
+ chunkqueue_mark_written(cq, weHave);
break;
}
- chunkqueue_remove_finished_chunks(cq);
}
-
switch ((err = xmlParseChunk(ctxt, 0, 0, 1))) {
case XML_ERR_DOCUMENT_END:
case XML_ERR_OK:
@@ -1764,12 +1760,10 @@ URIHANDLER_FUNC(mod_webdav_subrequest_handler) {
}
if (r > 0) {
- c->offset += r;
- cq->bytes_out += r;
+ chunkqueue_mark_written(cq, r);
} else {
break;
}
- chunkqueue_remove_finished_chunks(cq);
}
close(fd);