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,


Reply via email to