#include <strings.h>
#endif
-/* Make sure we don't write less than 4096 bytes at any one time.
- */
-#define MIN_BYTES_TO_WRITE 9000
-
/* LimitXMLRequestBody handling */
#define AP_LIMIT_UNSET ((long) -1)
#define AP_DEFAULT_LIMIT_XML_BODY ((size_t)1000000)
if (ctx == NULL) {
f->ctx = ctx = apr_pcalloc(p, sizeof(coalesce_filter_ctx_t));
- ctx->avail = MIN_BYTES_TO_WRITE;
+ ctx->avail = AP_MIN_BYTES_TO_WRITE;
}
if (ctx->cnt) {
if ((n < MIN_BUCKET_SIZE) && (n < ctx->avail)) {
/* Coalesce this bucket into the buffer */
if (ctx->buf == NULL) {
- ctx->buf = apr_palloc(p, MIN_BYTES_TO_WRITE);
+ ctx->buf = apr_palloc(p, AP_MIN_BYTES_TO_WRITE);
ctx->cur = ctx->buf;
ctx->cnt = 0;
}
if (ctx) {
ctx->cur = ctx->buf;
ctx->cnt = 0;
- ctx->avail = MIN_BYTES_TO_WRITE;
+ ctx->avail = AP_MIN_BYTES_TO_WRITE;
}
}
else {
/* Completed iterating over the brigades, now determine if we want to
* buffer the brigade or send the brigade out on the network
*/
- if ((!fd && (!more) && (nbytes < MIN_BYTES_TO_WRITE) && !AP_BUCKET_IS_FLUSH(e))
+ if ((!fd && (!more) && (nbytes < AP_MIN_BYTES_TO_WRITE) && !AP_BUCKET_IS_FLUSH(e))
|| (AP_BUCKET_IS_EOS(e) && c->keepalive)) {
/* NEVER save an EOS in here. If we are saving a brigade with an
struct content_length_ctx {
ap_bucket_brigade *saved;
- int hold_data; /* Whether or not to buffer the data. */
+ int compute_len;
};
/* This filter computes the content length, but it also computes the number
ctx = f->ctx;
if (!ctx) { /* first time through */
f->ctx = ctx = apr_pcalloc(r->pool, sizeof(struct content_length_ctx));
-
- /* We won't compute a content length if one of the following is true:
- * . subrequest
- * . HTTP/0.9
- * . status HTTP_NOT_MODIFIED or HTTP_NO_CONTENT
- * . HEAD
- * . content length already computed
- * . can be chunked
- * . body already chunked
- * Much of this should correspond to checks in ap_set_keepalive().
- */
- if ((r->assbackwards
- || r->status == HTTP_NOT_MODIFIED
- || r->status == HTTP_NO_CONTENT
- || r->header_only
- || r->proto_num == HTTP_VERSION(1,1)
- || ap_find_last_token(f->r->pool,
- apr_table_get(r->headers_out,
- "Transfer-Encoding"),
- "chunked"))
- && (!AP_BUCKET_IS_EOS(AP_BRIGADE_LAST(b)))) {
- ctx->hold_data = 0;
- }
- else {
- ctx->hold_data = 1;
- }
}
AP_BRIGADE_FOREACH(e, b) {
r->bytes_sent += length;
}
- if (ctx->hold_data) { /* calculating content length? */
+ if (r->bytes_sent < AP_MIN_BYTES_TO_WRITE) {
+ ap_save_brigade(f, &ctx->saved, &b);
+ return APR_SUCCESS;
+ }
+
+ /* We will compute a content length if:
+ * We already have all the data
+ * This is a bit confusing, because we will always buffer up
+ * to AP_MIN_BYTES_TO_WRITE, so if we get all the data while
+ * we are buffering that much data, we set the c-l.
+ * or We are in a 1.1 request and we can't chunk
+ * or This is a keepalive connection
+ * We may want to change this later to just close the connection
+ */
+ if ((r->proto_num == HTTP_VERSION(1,1)
+ && !ap_find_last_token(f->r->pool,
+ apr_table_get(r->headers_out,
+ "Transfer-Encoding"),
+ "chunked"))
+ || (f->r->connection->keepalive)
+ || (AP_BUCKET_IS_EOS(AP_BRIGADE_LAST(b)))) {
+ ctx->compute_len = 1;
+ }
+ else {
+ ctx->compute_len = 0;
+ }
+
+ if (ctx->compute_len) {
/* save the brigade; we can't pass any data to the next
* filter until we have the entire content length
*/
ap_save_brigade(f, &ctx->saved, &b);
return APR_SUCCESS;
}
- if (ctx->saved) {
- AP_BRIGADE_CONCAT(ctx->saved, b);
- b = ctx->saved;
- }
ap_set_content_length(r, r->bytes_sent);
}
+ if (ctx->saved) {
+ AP_BRIGADE_CONCAT(ctx->saved, b);
+ b = ctx->saved;
+ }
return ap_pass_brigade(f->next, b);
}