Author: rhuijben Date: Wed Nov 11 09:39:09 2015 New Revision: 1713788 URL: http://svn.apache.org/viewvc?rev=1713788&view=rev Log: Implement a best effort serf_default_readline() via read() and peek() to be used on buckets that don't have a specialized implementation and currently use a NULL function.
* buckets/buckets.c (serf_default_readline): New function. * buckets/dechunk_buckets.c (serf_bucket_type_dechunk): Use default api. * buckets/deflate_buckets.c (serf_bucket_type_deflate): Use default api. * buckets/hpack_buckets.c (serf_bucket_type__hpack): Use default api. * buckets/http2_frame_buckets.c (serf_bucket_type__http2_unframe): Use default api. * buckets/prefix_buckets.c (serf_bucket_type__http2_unpad): Use default api. * serf_bucket_util.h (serf_default_readline): New function. Modified: serf/trunk/buckets/buckets.c serf/trunk/buckets/dechunk_buckets.c serf/trunk/buckets/deflate_buckets.c serf/trunk/buckets/hpack_buckets.c serf/trunk/buckets/http2_frame_buckets.c serf/trunk/buckets/prefix_buckets.c serf/trunk/serf_bucket_util.h Modified: serf/trunk/buckets/buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/buckets.c?rev=1713788&r1=1713787&r2=1713788&view=diff ============================================================================== --- serf/trunk/buckets/buckets.c (original) +++ serf/trunk/buckets/buckets.c Wed Nov 11 09:39:09 2015 @@ -125,6 +125,93 @@ apr_status_t serf_default_peek( return APR_SUCCESS; } +apr_status_t serf_default_readline(serf_bucket_t *bucket, int acceptable, + int *found, + const char **data, apr_size_t *len) +{ + apr_status_t status; + const char *peek_data; + apr_size_t peek_len; + apr_size_t requested; + + status = bucket->type->peek(bucket, &peek_data, &peek_len); + + if (SERF_BUCKET_READ_ERROR(status)) + return status; + + if (peek_len > 0) { + const char *cr = NULL; + const char *lf = NULL; + + if ((acceptable & SERF_NEWLINE_CR) || (acceptable & SERF_NEWLINE_CRLF)) + cr = memchr(peek_data, '\r', peek_len); + if ((acceptable & SERF_NEWLINE_LF)) + lf = memchr(peek_data, '\n', peek_len); + + if (cr && lf) + cr = MIN(cr, lf); + else if (lf) + cr = lf; + + /* ### When we are only looking for CRLF we may return too small + chunks here when the data contains CR or LF without the other. + That isn't incorrect, but it could be optimized. + + ### But as that case is not common, the caller has to assume + partial reads anyway and this is just a not very inefficient + fallback implementation... + + Let's make the buffering in the caller handle that case + for now. */ + + if (*cr == '\r' && (acceptable & SERF_NEWLINE_CRLF) + && ((cr + 1) < (peek_data + peek_len)) && *(cr + 1) == '\n') + { + requested = (cr + 2) - peek_data; + } + else if (cr) + requested = (cr + 1) - peek_data; + else + requested = peek_len; + } + else { + /* We can't peek... + The only valid thing to do is try to read upto one EOL */ + if ((acceptable & SERF_NEWLINE_ANY) == SERF_NEWLINE_CRLF) + requested = 2; + else + requested = 1; + } + + status = bucket->type->read(bucket, requested, data, len); + + if (SERF_BUCKET_READ_ERROR(status)) + return status; + + if (*len == 0) { + *found = SERF_NEWLINE_NONE; + } + else if ((acceptable & SERF_NEWLINE_CRLF) && *len >= 2 + && data[*len - 1] == '\n' && data[*len - 2] == '\r') + { + *found = SERF_NEWLINE_CRLF; + } + else if ((acceptable & SERF_NEWLINE_LF) && data[*len - 1] == '\n') + { + *found = SERF_NEWLINE_LF; + } + else if ((acceptable & (SERF_NEWLINE_CRLF | SERF_NEWLINE_CR)) + && data[*len - 1] == '\r') + { + *found = (acceptable & (SERF_NEWLINE_CRLF)) ? SERF_NEWLINE_CRLF_SPLIT + : SERF_NEWLINE_CR; + } + else + *found = SERF_NEWLINE_NONE; + + return status; +} + void serf_default_destroy(serf_bucket_t *bucket) { Modified: serf/trunk/buckets/dechunk_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/dechunk_buckets.c?rev=1713788&r1=1713787&r2=1713788&view=diff ============================================================================== --- serf/trunk/buckets/dechunk_buckets.c (original) +++ serf/trunk/buckets/dechunk_buckets.c Wed Nov 11 09:39:09 2015 @@ -197,14 +197,10 @@ static apr_status_t serf_dechunk_set_con return serf_bucket_set_config(ctx->stream, config); } - -/* ### need to implement */ -#define serf_dechunk_readline NULL - const serf_bucket_type_t serf_bucket_type_dechunk = { "DECHUNK", serf_dechunk_read, - serf_dechunk_readline /* ### TODO */, + serf_default_readline, serf_default_read_iovec, serf_default_read_for_sendfile, serf_buckets_are_v2, Modified: serf/trunk/buckets/deflate_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/deflate_buckets.c?rev=1713788&r1=1713787&r2=1713788&view=diff ============================================================================== --- serf/trunk/buckets/deflate_buckets.c (original) +++ serf/trunk/buckets/deflate_buckets.c Wed Nov 11 09:39:09 2015 @@ -444,13 +444,10 @@ static apr_status_t serf_deflate_set_con return serf_bucket_set_config(ctx->stream, config); } -/* ### need to implement */ -#define serf_deflate_readline NULL - const serf_bucket_type_t serf_bucket_type_deflate = { "DEFLATE", serf_deflate_read, - serf_deflate_readline /* ### TODO */, + serf_default_readline, serf_default_read_iovec, serf_default_read_for_sendfile, serf_buckets_are_v2, Modified: serf/trunk/buckets/hpack_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/hpack_buckets.c?rev=1713788&r1=1713787&r2=1713788&view=diff ============================================================================== --- serf/trunk/buckets/hpack_buckets.c (original) +++ serf/trunk/buckets/hpack_buckets.c Wed Nov 11 09:39:09 2015 @@ -1029,13 +1029,10 @@ serf_hpack_destroy_and_data(serf_bucket_ } -/* ### need to implement */ -#define serf_hpack_readline NULL - const serf_bucket_type_t serf_bucket_type__hpack = { "HPACK", serf_hpack_read, - serf_hpack_readline, + serf_default_readline, serf_hpack_read_iovec, serf_default_read_for_sendfile, serf_buckets_are_v2, Modified: serf/trunk/buckets/http2_frame_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/http2_frame_buckets.c?rev=1713788&r1=1713787&r2=1713788&view=diff ============================================================================== --- serf/trunk/buckets/http2_frame_buckets.c (original) +++ serf/trunk/buckets/http2_frame_buckets.c Wed Nov 11 09:39:09 2015 @@ -322,13 +322,10 @@ serf_http2_unframe_get_remaining(serf_bu return ctx->payload_remaining; } -/* ### need to implement */ -#define serf_http2_unframe_readline NULL - const serf_bucket_type_t serf_bucket_type__http2_unframe = { "H2-UNFRAME", serf_http2_unframe_read, - serf_http2_unframe_readline /* ### TODO */, + serf_default_readline, serf_http2_unframe_read_iovec, serf_default_read_for_sendfile, serf_buckets_are_v2, @@ -587,13 +584,10 @@ serf_http2_unpad_get_remaining(serf_buck return ctx->payload_remaining; } -/* ### need to implement */ -#define serf_h2_dechunk_readline NULL - const serf_bucket_type_t serf_bucket_type__http2_unpad = { "H2-UNPAD", serf_http2_unpad_read, - serf_h2_dechunk_readline /* ### TODO */, + serf_default_readline, serf_http2_unpad_read_iovec, serf_default_read_for_sendfile, serf_buckets_are_v2, @@ -961,13 +955,10 @@ serf_http2_frame_destroy(serf_bucket_t * serf_default_destroy_and_data(bucket); } -/* ### need to implement */ -#define serf_http2_frame_readline NULL - const serf_bucket_type_t serf_bucket_type__http2_frame = { "H2-FRAME", serf_http2_frame_read, - serf_http2_frame_readline, + serf_default_readline, serf_http2_frame_read_iovec, serf_default_read_for_sendfile, serf_buckets_are_v2, Modified: serf/trunk/buckets/prefix_buckets.c URL: http://svn.apache.org/viewvc/serf/trunk/buckets/prefix_buckets.c?rev=1713788&r1=1713787&r2=1713788&view=diff ============================================================================== --- serf/trunk/buckets/prefix_buckets.c (original) +++ serf/trunk/buckets/prefix_buckets.c Wed Nov 11 09:39:09 2015 @@ -226,13 +226,10 @@ static void serf_prefix_destroy(serf_buc serf_default_destroy_and_data(bucket); } -/* ### need to implement */ -#define serf_prefix_readline NULL - const serf_bucket_type_t serf_bucket_type_prefix = { "prefix", serf_prefix_read, - serf_prefix_readline, /* #### */ + serf_default_readline, serf_prefix_read_iovec, serf_default_read_for_sendfile, serf_buckets_are_v2, Modified: serf/trunk/serf_bucket_util.h URL: http://svn.apache.org/viewvc/serf/trunk/serf_bucket_util.h?rev=1713788&r1=1713787&r2=1713788&view=diff ============================================================================== --- serf/trunk/serf_bucket_util.h (original) +++ serf/trunk/serf_bucket_util.h Wed Nov 11 09:39:09 2015 @@ -61,6 +61,17 @@ apr_status_t serf_default_read_iovec( int *vecs_used); /** + * Default implementation of the @see readline functionality. + * + * This function will use the @see read function, when possible optimized by + * the @a peek function to return the requested result. + */ +apr_status_t serf_default_readline(serf_bucket_t *bucket, int acceptable, + int *found, + const char **data, apr_size_t *len); + + +/** * Default implementation of the @see read_for_sendfile functionality. * * This function will use the @see read function to get a block of memory,