Author: rhuijben
Date: Sat Oct 31 13:52:51 2015
New Revision: 1711632
URL: http://svn.apache.org/viewvc?rev=1711632&view=rev
Log:
Tweak the http2 frame buckets to always return frame size errors when
there is less data in the frame than expected. APR_EOF notifies success,
which is not the right way to report missing data.
* buckets/http2_frame_buckets.c
(serf_http2_unframe_read,
serf_http2_unframe_read_iovec,
serf_http2_unpad_read_padsize): Properly handle APR_EOF.
(serf_http2_unpad_read): When reading more than payload, try to read
the padding as well, instead of explicitly keeping that for the
next read.
(serf_http2_unpad_read_iovec): Properly handle APR_EOF.
Modified:
serf/trunk/buckets/http2_frame_buckets.c
Modified: serf/trunk/buckets/http2_frame_buckets.c
URL:
http://svn.apache.org/viewvc/serf/trunk/buckets/http2_frame_buckets.c?rev=1711632&r1=1711631&r2=1711632&view=diff
==============================================================================
--- serf/trunk/buckets/http2_frame_buckets.c (original)
+++ serf/trunk/buckets/http2_frame_buckets.c Sat Oct 31 13:52:51 2015
@@ -227,6 +227,8 @@ serf_http2_unframe_read(serf_bucket_t *b
if (!SERF_BUCKET_READ_ERROR(status))
status = APR_EOF;
}
+ else if (APR_STATUS_IS_EOF(status))
+ return SERF_ERROR_HTTP2_FRAME_SIZE_ERROR;
}
return status;
@@ -280,6 +282,8 @@ serf_http2_unframe_read_iovec(serf_bucke
if (!SERF_BUCKET_READ_ERROR(status))
status = APR_EOF;
}
+ else if (APR_STATUS_IS_EOF(status))
+ return SERF_ERROR_HTTP2_FRAME_SIZE_ERROR;
}
return status;
@@ -418,6 +422,8 @@ serf_http2_unpad_read_padsize(serf_bucke
ctx->payload_remaining = (apr_size_t)remaining - ctx->pad_length;
}
+ else if (APR_STATUS_IS_EOF(status))
+ status = SERF_ERROR_HTTP2_FRAME_SIZE_ERROR;
else if (!status)
status = APR_EAGAIN;
@@ -467,19 +473,37 @@ serf_http2_unpad_read(serf_bucket_t *buc
*len = 0;
return status;
}
- else if (ctx->payload_remaining == 0)
+ else if (ctx->payload_remaining == 0
+ && ctx->pad_remaining == 0)
{
*len = 0;
- return serf_http2_unpad_read_padding(bucket);
+ return APR_EOF;
}
- if (requested > ctx->payload_remaining)
- requested = ctx->payload_remaining;
+
+ if (requested >= ctx->payload_remaining)
+ requested = ctx->payload_remaining + ctx->pad_remaining;
status = serf_bucket_read(ctx->stream, requested, data, len);
if (! SERF_BUCKET_READ_ERROR(status))
{
- ctx->payload_remaining -= *len;
+ if (*len <= ctx->payload_remaining)
+ ctx->payload_remaining -= *len;
+ else
+ {
+ ctx->pad_remaining -= (*len - ctx->payload_remaining);
+ *len = ctx->payload_remaining;
+ ctx->payload_remaining = 0;
+
+ if (ctx->pad_remaining == 0)
+ status = APR_EOF;
+ }
+
+ if (APR_STATUS_IS_EOF(status)
+ && (ctx->pad_remaining != 0 || ctx->payload_remaining != 0))
+ {
+ status = SERF_ERROR_HTTP2_FRAME_SIZE_ERROR;
+ }
}
return status;
@@ -508,6 +532,7 @@ serf_http2_unpad_read_iovec(serf_bucket_
return serf_http2_unpad_read_padding(bucket);
}
+ /* ### Can we read data and padding in one go? */
if (requested > ctx->payload_remaining)
requested = ctx->payload_remaining;
@@ -522,6 +547,12 @@ serf_http2_unpad_read_iovec(serf_bucket_
len += vecs[i].iov_len;
ctx->payload_remaining -= len;
+
+ if (APR_STATUS_IS_EOF(status)
+ && (ctx->pad_remaining != 0 || ctx->payload_remaining != 0))
+ {
+ status = SERF_ERROR_HTTP2_FRAME_SIZE_ERROR;
+ }
}
return status;