Browse Source

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
svn/tags/lighttpd-1.4.37
Stefan Bühler 7 years ago
parent
commit
26226271de
  1. 170
      src/chunk.c
  2. 1
      src/connections.c
  3. 43
      src/mod_cgi.c
  4. 19
      src/mod_fastcgi.c
  5. 1
      src/mod_proxy.c
  6. 1
      src/mod_scgi.c
  7. 12
      src/mod_webdav.c

170
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;

1
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;
}

43
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);
}
}

19
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;
}

1
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);

1
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);

12
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);

Loading…
Cancel
Save