Author: rhuijben
Date: Sat Oct 17 16:39:48 2015
New Revision: 1709194
URL: http://svn.apache.org/viewvc?rev=1709194&view=rev
Log:
Improve the limit buckets a bit using new knowledge from the http2 buckets.
* serf-dev/dev/buckets/limit_buckets.c
(serf_limit_readline): Document limitation.
(serf_limit_read_iovec): New function.
(serf_limit_peek): Limit the result.
(serf_bucket_type_limit): Add serf_limit_read_iovec.
Modified:
serf/trunk/buckets/limit_buckets.c
Modified: serf/trunk/buckets/limit_buckets.c
URL:
http://svn.apache.org/viewvc/serf/trunk/buckets/limit_buckets.c?rev=1709194&r1=1709193&r2=1709194&view=diff
==============================================================================
--- serf/trunk/buckets/limit_buckets.c (original)
+++ serf/trunk/buckets/limit_buckets.c Sat Oct 17 16:39:48 2015
@@ -88,9 +88,10 @@ static apr_status_t serf_limit_readline(
*found = SERF_NEWLINE_NONE;
return APR_EOF;
}
-
+ /* ### Where does this obey/verify the limit? -> It doesn't */
status = serf_bucket_readline(ctx->stream, acceptable, found, data, len);
+ /* So this may potentially underflow! */
if (!SERF_BUCKET_READ_ERROR(status)) {
ctx->remaining -= *len;
}
@@ -103,13 +104,62 @@ static apr_status_t serf_limit_readline(
return status;
}
+static apr_status_t serf_limit_read_iovec(serf_bucket_t *bucket,
+ apr_size_t requested,
+ int vecs_size,
+ struct iovec *vecs,
+ int *vecs_used)
+{
+ limit_context_t *ctx = bucket->data;
+ apr_status_t status;
+
+ if (!ctx->remaining) {
+ *vecs_used = 0;
+ return APR_EOF;
+ }
+
+ if (requested == SERF_READ_ALL_AVAIL || requested > ctx->remaining) {
+ if (ctx->remaining <= REQUESTED_MAX) {
+ requested = (apr_size_t) ctx->remaining;
+ } else {
+ requested = REQUESTED_MAX;
+ }
+ }
+
+ status = serf_bucket_read_iovec(ctx->stream, requested,
+ vecs_size, vecs, vecs_used);
+ if (!SERF_BUCKET_READ_ERROR(status)) {
+ int i;
+ apr_size_t len = 0;
+
+ for (i = 0; i < *vecs_used; i++)
+ len += vecs[i].iov_len;
+
+ ctx->remaining -= len;
+ }
+
+ /* If we have met our limit and don't have a status, return EOF. */
+ if (!ctx->remaining && !status) {
+ status = APR_EOF;
+ }
+
+ return status;
+}
+
static apr_status_t serf_limit_peek(serf_bucket_t *bucket,
const char **data,
apr_size_t *len)
{
limit_context_t *ctx = bucket->data;
+ apr_status_t status;
- return serf_bucket_peek(ctx->stream, data, len);
+ status = serf_bucket_peek(ctx->stream, data, len);
+
+ if (!SERF_BUCKET_READ_ERROR(status)) {
+ if (*len > ctx->remaining)
+ *len = (apr_size_t)ctx->remaining;
+ }
+ return status;
}
static void serf_limit_destroy(serf_bucket_t *bucket)
@@ -142,7 +192,7 @@ const serf_bucket_type_t serf_bucket_typ
"LIMIT",
serf_limit_read,
serf_limit_readline,
- serf_default_read_iovec,
+ serf_limit_read_iovec,
serf_default_read_for_sendfile,
serf_buckets_are_v2,
serf_limit_peek,