Author: rhuijben
Date: Wed Nov 11 13:16:46 2015
New Revision: 1713834
URL: http://svn.apache.org/viewvc?rev=1713834&view=rev
Log:
Extend the linebuf crlf test to show that we have a huge problem with
some bucket types. I really hope that nobody encountered this in the
real world.
I have no proper solution to solve this problem yet, but I can imagine
seeing this problem in certain cases where we didn't implement peek yet.
* buckets/buckets.c
(serf_linebuf_fetch): Note problem (twice).
* test/test_buckets.c
(test_linebuf_fetch_crlf): Extend regression test to trigger this problem.
Modified:
serf/trunk/buckets/buckets.c
serf/trunk/test/test_buckets.c
Modified: serf/trunk/buckets/buckets.c
URL:
http://svn.apache.org/viewvc/serf/trunk/buckets/buckets.c?rev=1713834&r1=1713833&r2=1713834&view=diff
==============================================================================
--- serf/trunk/buckets/buckets.c (original)
+++ serf/trunk/buckets/buckets.c Wed Nov 11 13:16:46 2015
@@ -703,6 +703,10 @@ apr_status_t serf_linebuf_fetch(
* split CRLF.
*/
+ /* ### We can't assume peek will ever return any data!
+ Just check serf_default_peek()
+
+ ### We would be stuck here forever */
status = serf_bucket_peek(bucket, &data, &len);
if (SERF_BUCKET_READ_ERROR(status))
return status;
@@ -726,6 +730,11 @@ apr_status_t serf_linebuf_fetch(
/* Whatever was read, the line is now ready for use. */
linebuf->state = SERF_LINEBUF_READY;
} else {
+ /* ### We can't assume peek will ever return any data!
+ Just check serf_default_peek()
+
+ ### We would be stuck here forever */
+
/* no data available, try again later. */
return APR_EAGAIN;
}
Modified: serf/trunk/test/test_buckets.c
URL:
http://svn.apache.org/viewvc/serf/trunk/test/test_buckets.c?rev=1713834&r1=1713833&r2=1713834&view=diff
==============================================================================
--- serf/trunk/test/test_buckets.c (original)
+++ serf/trunk/test/test_buckets.c Wed Nov 11 13:16:46 2015
@@ -2003,6 +2003,8 @@ static void test_linebuf_fetch_crlf(CuTe
};
serf_bucket_t *bkt;
serf_linebuf_t linebuf;
+ serf_bucket_type_t *unfriendly;
+ apr_status_t status;
serf_bucket_alloc_t *alloc = test__create_bucket_allocator(tc, tb->pool);
@@ -2041,6 +2043,52 @@ static void test_linebuf_fetch_crlf(CuTe
CuAssertIntEquals(tc, 0, linebuf.used);
serf_bucket_destroy(bkt);
+
+ /* And now try again with a less frienly peek implementation */
+ bkt = serf_bucket_mock_create(actions, sizeof(actions) /
sizeof(actions[0]),
+ alloc);
+
+ unfriendly = serf_bmemdup(alloc, bkt->type, sizeof(*bkt->type));
+ unfriendly->peek = serf_default_peek; /* Unable to peek */
+ bkt->type = unfriendly;
+
+ serf_linebuf_init(&linebuf);
+ CuAssertStrEquals(tc, "", linebuf.line);
+ CuAssertIntEquals(tc, 0, linebuf.used);
+ CuAssertIntEquals(tc, SERF_LINEBUF_EMPTY, linebuf.state);
+
+ CuAssertIntEquals(tc, APR_SUCCESS,
+ serf_linebuf_fetch(&linebuf, bkt, SERF_NEWLINE_CRLF));
+ /* We got first line in one call. */
+ CuAssertIntEquals(tc, SERF_LINEBUF_READY, linebuf.state);
+ CuAssertStrEquals(tc, "line1", linebuf.line);
+ CuAssertIntEquals(tc, 5, linebuf.used);
+
+ /* The second line CR and LF splitted across packets. */
+ CuAssertIntEquals(tc, APR_EAGAIN,
+ serf_linebuf_fetch(&linebuf, bkt, SERF_NEWLINE_CRLF));
+ CuAssertIntEquals(tc, SERF_LINEBUF_CRLF_SPLIT, linebuf.state);
+
+ /* This test gets now stuck here, because EAGAIN will be returned forever
*/
+ CuAssertIntEquals(tc, APR_EAGAIN,
+ serf_linebuf_fetch(&linebuf, bkt, SERF_NEWLINE_CRLF));
+ CuAssertIntEquals(tc, SERF_LINEBUF_CRLF_SPLIT, linebuf.state);
+
+#if 0
+ CuAssertIntEquals(tc, SERF_LINEBUF_READY, linebuf.state);
+ CuAssertIntEquals(tc, 5, linebuf.used);
+ CuAssertStrnEquals(tc, "line2", 0, linebuf.line);
+
+ /* Last line is empty. */
+ CuAssertIntEquals(tc, APR_EOF,
+ serf_linebuf_fetch(&linebuf, bkt, SERF_NEWLINE_CRLF));
+ CuAssertIntEquals(tc, SERF_LINEBUF_READY, linebuf.state);
+ CuAssertStrEquals(tc, "", linebuf.line);
+ CuAssertIntEquals(tc, 0, linebuf.used);
+
+ serf_bucket_destroy(bkt);
+ serf_bucket_mem_free(alloc, unfriendly);
+#endif
}
typedef struct prefix_cb