Author: rhuijben
Date: Wed Nov 25 01:29:14 2015
New Revision: 1716290
URL: http://svn.apache.org/viewvc?rev=1716290&view=rev
Log:
* buckets/fcgi_buckets.c
(serf__bucket_fcgi_unframe_read_info): Retry reading when possible.
Handle more status values on record completely read.
* buckets/http2_frame_buckets.c
(serf__bucket_http2_unframe_read_info): Stop folding several status
values to APR_SUCCESS.
* protocols/http2_buckets.h
(serf__bucket_hpack_decode_create): Update documentation.
Modified:
serf/trunk/buckets/fcgi_buckets.c
serf/trunk/buckets/http2_frame_buckets.c
serf/trunk/protocols/http2_buckets.h
Modified: serf/trunk/buckets/fcgi_buckets.c
URL:
http://svn.apache.org/viewvc/serf/trunk/buckets/fcgi_buckets.c?rev=1716290&r1=1716289&r2=1716290&view=diff
==============================================================================
--- serf/trunk/buckets/fcgi_buckets.c (original)
+++ serf/trunk/buckets/fcgi_buckets.c Wed Nov 25 01:29:14 2015
@@ -74,8 +74,7 @@ apr_status_t serf__bucket_fcgi_unframe_r
apr_uint16_t *frame_type)
{
fcgi_unframe_ctx_t *ctx = bucket->data;
- const char *data;
- apr_size_t len;
+ const unsigned char *header;
apr_status_t status;
if (ctx->record_remaining == 0)
@@ -88,71 +87,74 @@ apr_status_t serf__bucket_fcgi_unframe_r
return APR_SUCCESS;
}
- status = serf_bucket_read(ctx->stream, ctx->record_remaining, &data, &len);
- if (!SERF_BUCKET_READ_ERROR(status))
+ do
{
- const unsigned char *header;
+ const char *data;
+ apr_size_t len;
- if (len < FCGI_RECORD_SIZE)
- {
+ status = serf_bucket_read(ctx->stream, ctx->record_remaining, &data,
&len);
+
+ if (SERF_BUCKET_READ_ERROR(status))
+ return status;
+
+ if (len < FCGI_RECORD_SIZE) {
memcpy(ctx->buffer + FCGI_RECORD_SIZE - ctx->record_remaining,
data, len);
ctx->record_remaining -= len;
header = ctx->buffer;
}
- else
- {
+ else {
header = (const void *)data;
ctx->record_remaining = 0;
}
+ } while (!status && ctx->record_remaining > 0);
- if (ctx->record_remaining == 0)
- {
- /* We combine version and frametype in a single value */
- ctx->frame_type = (header[0] << 8) | header[1];
- ctx->streamid = (header[2] << 8) | header[3];
- ctx->payload_remaining = (header[4] << 8) | header[5];
- /* header[6] is reserved */
- ctx->pad_remaining = header[7];
-
- /* Fill output arguments if necessary */
- if (stream_id)
- *stream_id = ctx->streamid;
- if (frame_type)
- *frame_type = ctx->frame_type;
-
- status = (ctx->payload_remaining == 0) ? APR_EOF
- : APR_SUCCESS;
-
- /* If we hava a zero-length frame we have to call the eof callback
- now, as the read operations will just shortcut to APR_EOF */
- if (ctx->payload_remaining == 0 && ctx->end_of_frame)
- {
- apr_status_t cb_status;
-
- cb_status = (*ctx->end_of_frame)(ctx->end_of_frame_baton,
- bucket);
-
- ctx->end_of_frame = NULL;
-
- if (SERF_BUCKET_READ_ERROR(cb_status))
- status = cb_status;
- }
- }
+ if (ctx->record_remaining == 0)
+ {
+ /* We combine version and frametype in a single value */
+ ctx->frame_type = (header[0] << 8) | header[1];
+ ctx->streamid = (header[2] << 8) | header[3];
+ ctx->payload_remaining = (header[4] << 8) | header[5];
+ /* header[6] is reserved */
+ ctx->pad_remaining = header[7];
+
+ /* Fill output arguments if necessary */
+ if (stream_id)
+ *stream_id = ctx->streamid;
+ if (frame_type)
+ *frame_type = ctx->frame_type;
+
+ if (ctx->payload_remaining == 0)
+ status = APR_EOF;
else if (APR_STATUS_IS_EOF(status))
+ status = SERF_ERROR_TRUNCATED_STREAM;
+
+ /* If we hava a zero-length frame we have to call the eof callback
+ now, as the read operations will just shortcut to APR_EOF */
+ if (ctx->payload_remaining == 0 && ctx->end_of_frame)
{
- /* Reading frame failed because we couldn't read the header. Report
- a read failure instead of semi-success */
- if (ctx->record_remaining == FCGI_RECORD_SIZE)
- status = SERF_ERROR_EMPTY_STREAM;
- else
- status = SERF_ERROR_TRUNCATED_STREAM;
- }
- else if (!status)
- status = APR_EAGAIN;
+ apr_status_t cb_status;
+
+ cb_status = (*ctx->end_of_frame)(ctx->end_of_frame_baton,
+ bucket);
+ ctx->end_of_frame = NULL;
+
+ if (SERF_BUCKET_READ_ERROR(cb_status))
+ status = cb_status;
+ }
+ }
+ else if (APR_STATUS_IS_EOF(status))
+ {
+ /* Reading frame failed because we couldn't read the header. Report
+ a read failure instead of semi-success */
+ if (ctx->record_remaining == FCGI_RECORD_SIZE)
+ status = SERF_ERROR_EMPTY_STREAM;
+ else
+ status = SERF_ERROR_TRUNCATED_STREAM;
}
+
return status;
}
Modified: serf/trunk/buckets/http2_frame_buckets.c
URL:
http://svn.apache.org/viewvc/serf/trunk/buckets/http2_frame_buckets.c?rev=1716290&r1=1716289&r2=1716290&view=diff
==============================================================================
--- serf/trunk/buckets/http2_frame_buckets.c (original)
+++ serf/trunk/buckets/http2_frame_buckets.c Wed Nov 25 01:29:14 2015
@@ -166,8 +166,10 @@ serf__bucket_http2_unframe_read_info(ser
return SERF_ERROR_HTTP2_FRAME_SIZE_ERROR;
}
- status = (ctx->payload_remaining == 0) ? APR_EOF
- : APR_SUCCESS;
+ if (ctx->payload_remaining == 0)
+ status = APR_EOF;
+ else if (APR_STATUS_IS_EOF(status))
+ status = SERF_ERROR_TRUNCATED_STREAM;
/* If we hava a zero-length frame we have to call the eof callback
now, as the read operations will just shortcut to APR_EOF */
Modified: serf/trunk/protocols/http2_buckets.h
URL:
http://svn.apache.org/viewvc/serf/trunk/protocols/http2_buckets.h?rev=1716290&r1=1716289&r2=1716290&view=diff
==============================================================================
--- serf/trunk/protocols/http2_buckets.h (original)
+++ serf/trunk/protocols/http2_buckets.h Wed Nov 25 01:29:14 2015
@@ -178,7 +178,7 @@ extern const serf_bucket_type_t serf_buc
#define SERF_BUCKET_IS_HPACK_DECODE(b) SERF_BUCKET_CHECK((b), hpack_decode)
/* If ITEM_CALLBACK is not null calls it for every item while reading, and
- the bucket will just return no data and APR_EAGAIN until done.
+ the bucket will just return no data until EOF.
If ITEM_CALLBACK is NULL, the bucket will read as a HTTP/1 like header
block,
starting with a status line and ending with "\r\n\r\n", which allows using