jwoolley 01/06/13 09:48:50
Modified: modules/http http_protocol.c
. CHANGES
buckets apr_brigade.c
include apr_buckets.h
Log:
* apr_brigade_partition() now returns an apr_status_t (finally!).
* did some code cleanups/optimizations in that function.
* updated Apache's byterange filter to handle the new prototype. added
error handling to the byterange filter should apr_brigade_partition()
ever fail, which it never will unless somebody either removes the earlier
call to apr_brigade_length() for some unknown reason or invents a new
bucket type that is of a predetermined length but which cannot be split
natively (or which has a split that might fail). might as well be
future-proof.
Revision Changes Path
1.326 +18 -7 httpd-2.0/modules/http/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
retrieving revision 1.325
retrieving revision 1.326
diff -u -d -u -r1.325 -r1.326
--- http_protocol.c 2001/06/13 13:44:37 1.325
+++ http_protocol.c 2001/06/13 16:48:37 1.326
@@ -2227,6 +2227,8 @@
}
#define BYTERANGE_FMT "%" APR_OFF_T_FMT "-%" APR_OFF_T_FMT "/%" APR_OFF_T_FMT
+#define PARTITION_ERR_FMT "apr_brigade_partition() failed " \
+ "[%" APR_OFF_T_FMT ",%" APR_OFF_T_FMT "]"
AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(
ap_filter_t *f,
@@ -2320,11 +2322,24 @@
if (rv == -1) {
continue;
- }
- else {
- found = 1;
}
+ /* these calls to apr_brigade_partition() should theoretically
+ * never fail because of the above call to apr_brigade_length(),
+ * but what the heck, we'll check for an error anyway */
+ if ((rv = apr_brigade_partition(bb, range_start, &ec)) !=
APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ PARTITION_ERR_FMT, range_start, clength);
+ continue;
+ }
+ if ((rv = apr_brigade_partition(bb, range_end+1, &e2)) !=
APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ PARTITION_ERR_FMT, range_end+1, clength);
+ continue;
+ }
+
+ found = 1;
+
if (ctx->num_ranges > 1) {
char *ts;
@@ -2339,10 +2354,6 @@
APR_BRIGADE_INSERT_TAIL(bsend, e);
}
- e = apr_brigade_partition(bb, range_start);
- e2 = apr_brigade_partition(bb, range_end + 1);
-
- ec = e;
do {
apr_bucket *foo;
const char *str;
1.21 +2 -0 apr-util/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr-util/CHANGES,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -u -r1.20 -r1.21
--- CHANGES 2001/06/01 23:47:15 1.20
+++ CHANGES 2001/06/13 16:48:41 1.21
@@ -1,5 +1,7 @@
Changes with APR-util b1
+ *) apr_brigade_partition() now returns an apr_status_t. [Cliff Woolley]
+
*) Add MD4 implementation in crypto. [Sander Striker, Justin Erenkrantz]
*) Moved httpd 2.0.18's util_date to apr_date and enhanced its parsing
1.17 +34 -27 apr-util/buckets/apr_brigade.c
Index: apr_brigade.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_brigade.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -u -r1.16 -r1.17
--- apr_brigade.c 2001/06/08 11:00:36 1.16
+++ apr_brigade.c 2001/06/13 16:48:44 1.17
@@ -127,48 +127,55 @@
return a;
}
-APU_DECLARE(apr_bucket *) apr_brigade_partition(apr_bucket_brigade *b,
apr_off_t point)
+APU_DECLARE(apr_status_t) apr_brigade_partition(apr_bucket_brigade *b,
+ apr_off_t point,
+ apr_bucket **after_point)
{
apr_bucket *e;
const char *s;
apr_size_t len;
+ apr_status_t rv;
- if (point < 0)
- return NULL;
+ if (point < 0) {
+ /* this could cause weird (not necessarily SEGV) things to happen */
+ return APR_EINVAL;
+ }
+ if (point == 0) {
+ *after_point = APR_BRIGADE_FIRST(b);
+ return APR_SUCCESS;
+ }
APR_BRIGADE_FOREACH(e, b) {
- /* bucket is of a known length */
- if ((point > e->length) && (e->length != -1)) {
- if (APR_BUCKET_IS_EOS(e))
- return NULL;
- point -= e->length;
- }
- else if (point == e->length) {
- return APR_BUCKET_NEXT(e);
- }
- else {
+ if ((point < e->length) || (e->length == -1)) {
/* try to split the bucket natively */
- if (apr_bucket_split(e, point) != APR_ENOTIMPL)
- return APR_BUCKET_NEXT(e);
+ if ((rv = apr_bucket_split(e, point)) != APR_ENOTIMPL) {
+ *after_point = APR_BUCKET_NEXT(e);
+ return rv;
+ }
/* if the bucket cannot be split, we must read from it,
* changing its type to one that can be split */
- if (apr_bucket_read(e, &s, &len, APR_BLOCK_READ) != APR_SUCCESS)
- return NULL;
+ if ((rv = apr_bucket_read(e, &s, &len,
+ APR_BLOCK_READ)) != APR_SUCCESS) {
+ return rv;
+ }
- if (point < len) {
- if (apr_bucket_split(e, point) == APR_SUCCESS)
- return APR_BUCKET_NEXT(e);
- else
- return NULL;
+ /* this assumes that len == e->length, which is okay because e
+ * might have been morphed by the apr_bucket_read() above, but
+ * if it was, the length would have been adjusted appropriately
*/
+ if (point < e->length) {
+ rv = apr_bucket_split(e, point);
+ *after_point = APR_BUCKET_NEXT(e);
+ return rv;
}
- else if (point == len)
- return APR_BUCKET_NEXT(e);
- else
- point -= len;
}
+ if (point == e->length) {
+ *after_point = APR_BUCKET_NEXT(e);
+ return APR_SUCCESS;
+ }
+ point -= e->length;
}
- return NULL;
+ return APR_EINVAL;
}
APU_DECLARE(apr_status_t) apr_brigade_length(apr_bucket_brigade *bb,
1.98 +5 -4 apr-util/include/apr_buckets.h
Index: apr_buckets.h
===================================================================
RCS file: /home/cvs/apr-util/include/apr_buckets.h,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -d -u -r1.97 -r1.98
--- apr_buckets.h 2001/06/08 11:00:24 1.97
+++ apr_buckets.h 2001/06/13 16:48:46 1.98
@@ -634,11 +634,12 @@
* of bytes from the brigade; the ranges can even overlap.
* @param b The brigade to partition
* @param point The offset at which to partition the brigade
- * @return A pointer to the first bucket after the partition;
- * or NULL in any error condition (including partition past the end)
- * @deffunc apr_bucket *apr_brigade_partition(apr_bucket_brigade *b,
apr_off_t point)
+ * @param after_point Returns a pointer to the first bucket after the
partition
+ * @deffunc apr_status_t apr_brigade_partition(apr_bucket_brigade *b,
apr_off_t point, apr_bucket **after_point)
*/
-APU_DECLARE(apr_bucket *) apr_brigade_partition(apr_bucket_brigade *b,
apr_off_t point);
+APU_DECLARE(apr_status_t) apr_brigade_partition(apr_bucket_brigade *b,
+ apr_off_t point,
+ apr_bucket **after_point);
#if APR_NOT_DONE_YET
/**