static apr_status_t ssl_io_filter_Output(ap_filter_t *f,
apr_bucket_brigade *bb)
{
- SSLFilterRec *ctx = f->ctx;
- apr_bucket *bucket;
- apr_status_t ret = APR_SUCCESS;
+ apr_status_t status = APR_SUCCESS;
while (!APR_BRIGADE_EMPTY(bb)) {
- const char *data;
- apr_size_t len;
-
- bucket = APR_BRIGADE_FIRST(bb);
+ apr_bucket *bucket = APR_BRIGADE_FIRST(bb);
/* If it is a flush or EOS, we need to pass this down.
* These types do not require translation by OpenSSL.
*/
if (APR_BUCKET_IS_EOS(bucket) || APR_BUCKET_IS_FLUSH(bucket)) {
- apr_bucket_brigade *outbb;
- int done = APR_BUCKET_IS_EOS(bucket);
+ SSLFilterRec *ctx = f->ctx;
- if ((ret = BIO_bucket_flush(ctx->pbioWrite)) != APR_SUCCESS) {
- return ret;
+ if ((status = BIO_bucket_flush(ctx->pbioWrite)) != APR_SUCCESS) {
+ return status;
}
- outbb = apr_brigade_create(f->c->pool);
- APR_BUCKET_REMOVE(bucket);
- APR_BRIGADE_INSERT_TAIL(outbb, bucket);
- ret = ap_pass_brigade(f->next, outbb);
- if (ret != APR_SUCCESS) {
- return ret;
- }
+ if (APR_BUCKET_IS_EOS(bucket)) {
+ /* By definition, nothing can come after EOS.
+ * which also means we can pass the rest of this brigade
+ * without creating a new one since it only contains the
+ * EOS bucket.
+ */
- /* By definition, nothing can come after EOS. */
- if (done) {
+ if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
+ return status;
+ }
break;
}
+ else {
+ /* BIO_bucket_flush() already passed down a flush bucket
+ * if there was any data to be flushed.
+ */
+ apr_bucket_delete(bucket);
+ }
}
else {
/* read filter */
+ const char *data;
+ apr_size_t len;
+
apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);
- ret = ssl_filter_write(f, data, len);
+ status = ssl_filter_write(f, data, len);
apr_bucket_delete(bucket);
- if (ret != APR_SUCCESS) {
+ if (status != APR_SUCCESS) {
break;
}
}
}
- apr_brigade_destroy(bb);
- return ret;
+ return status;
}
/*