static void remove_empty_buckets(apr_bucket_brigade *bb) { apr_bucket *bucket; while (((bucket = APR_BRIGADE_FIRST(bb)) != APR_BRIGADE_SENTINEL(bb)) && (APR_BUCKET_IS_METADATA(bucket) || (bucket->length == 0))) { APR_BUCKET_REMOVE(bucket); apr_bucket_destroy(bucket); } }
APU_DECLARE(apr_status_t) apr_brigade_split_line(apr_bucket_brigade *bbOut, apr_bucket_brigade *bbIn, apr_read_type_e block, apr_off_t maxbytes) { apr_off_t readbytes = 0; while (!APR_BRIGADE_EMPTY(bbIn)) { const char *pos; const char *str; apr_size_t len; apr_status_t rv; apr_bucket *e; e = APR_BRIGADE_FIRST(bbIn); rv = apr_bucket_read(e, &str, &len, block); if (rv != APR_SUCCESS) { return rv; } pos = memchr(str, APR_ASCII_LF, len); /* We found a match. */ if (pos != NULL) { apr_bucket_split(e, pos - str + 1); APR_BUCKET_REMOVE(e); APR_BRIGADE_INSERT_TAIL(bbOut, e); return APR_SUCCESS; } APR_BUCKET_REMOVE(e); if (APR_BUCKET_IS_METADATA(e) || len > APR_BUCKET_BUFF_SIZE/4) { APR_BRIGADE_INSERT_TAIL(bbOut, e); } else { if (len > 0) { rv = apr_brigade_write(bbOut, NULL, NULL, str, len); if (rv != APR_SUCCESS) { return rv; } } apr_bucket_destroy(e); } readbytes += len; /* We didn't find an APR_ASCII_LF within the maximum line length. */ if (readbytes >= maxbytes) { break; } } return APR_SUCCESS; }
void h2_task_destroy(h2_task *task) { if (task->output.beam) { h2_beam_log(task->output.beam, task->c, APLOG_TRACE2, "task_destroy"); h2_beam_destroy(task->output.beam); task->output.beam = NULL; } if (task->eor) { apr_bucket_destroy(task->eor); } if (task->pool) { apr_pool_destroy(task->pool); } }
static int getsfunc_BRIGADE(char *buf, int len, void *arg) { apr_bucket_brigade *bb = (apr_bucket_brigade *)arg; const char *dst_end = buf + len - 1; /* leave room for terminating null */ char *dst = buf; apr_bucket *e = APR_BRIGADE_FIRST(bb); apr_status_t rv; int done = 0; while ((dst < dst_end) && !done && !APR_BUCKET_IS_EOS(e)) { const char *bucket_data; apr_size_t bucket_data_len; const char *src; const char *src_end; apr_bucket * next; rv = apr_bucket_read(e, &bucket_data, &bucket_data_len, APR_BLOCK_READ); if (rv != APR_SUCCESS || (bucket_data_len == 0)) { return APR_STATUS_IS_TIMEUP(rv) ? -1 : 0; } src = bucket_data; src_end = bucket_data + bucket_data_len; while ((src < src_end) && (dst < dst_end) && !done) { if (*src == '\n') { done = 1; } else if (*src != '\r') { *dst++ = *src; } src++; } if (src < src_end) { apr_bucket_split(e, src - bucket_data); } next = APR_BUCKET_NEXT(e); APR_BUCKET_REMOVE(e); apr_bucket_destroy(e); e = next; } *dst = 0; return 1; }
// Called when Apache outputs data: static apr_status_t firstbyte_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) { firstbyte_config_t *cf = ap_get_module_config(f->c->conn_config, &log_firstbyte_module); apr_bucket *b = APR_BRIGADE_LAST(bb); /* End of data, make sure we flush */ if (APR_BUCKET_IS_EOS(b)) { APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_flush_create(f->c->bucket_alloc)); APR_BUCKET_REMOVE(b); apr_bucket_destroy(b); } if (cf->first_out==1) { cf->first_out_time = apr_time_now(); cf->first_out = 0; } return ap_pass_brigade(f->next, bb); }
static apr_status_t copy_brigade_range(apr_bucket_brigade *bb, apr_bucket_brigade *bbout, apr_off_t start, apr_off_t end) { apr_bucket *first = NULL, *last = NULL, *out_first = NULL, *e; apr_uint64_t pos = 0, off_first = 0, off_last = 0; apr_status_t rv; apr_uint64_t start64, end64; apr_off_t pofft = 0; /* * Once we know that start and end are >= 0 convert everything to apr_uint64_t. * See the comments in apr_brigade_partition why. * In short apr_off_t (for values >= 0)and apr_size_t fit into apr_uint64_t. */ start64 = (apr_uint64_t)start; end64 = (apr_uint64_t)end; if (start < 0 || end < 0 || start64 > end64) return APR_EINVAL; for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb); e = APR_BUCKET_NEXT(e)) { apr_uint64_t elen64; /* we know that no bucket has undefined length (-1) */ AP_DEBUG_ASSERT(e->length != (apr_size_t)(-1)); elen64 = (apr_uint64_t)e->length; if (!first && (elen64 + pos > start64)) { first = e; off_first = pos; } if (elen64 + pos > end64) { last = e; off_last = pos; break; } pos += elen64; } if (!first || !last) return APR_EINVAL; e = first; while (1) { apr_bucket *copy; AP_DEBUG_ASSERT(e != APR_BRIGADE_SENTINEL(bb)); rv = apr_bucket_copy(e, ©); if (rv != APR_SUCCESS) { apr_brigade_cleanup(bbout); return rv; } APR_BRIGADE_INSERT_TAIL(bbout, copy); if (e == first) { if (off_first != start64) { rv = apr_bucket_split(copy, (apr_size_t)(start64 - off_first)); if (rv != APR_SUCCESS) { apr_brigade_cleanup(bbout); return rv; } out_first = APR_BUCKET_NEXT(copy); APR_BUCKET_REMOVE(copy); apr_bucket_destroy(copy); } else { out_first = copy; } } if (e == last) { if (e == first) { off_last += start64 - off_first; copy = out_first; } if (end64 - off_last != (apr_uint64_t)e->length) { rv = apr_bucket_split(copy, (apr_size_t)(end64 + 1 - off_last)); if (rv != APR_SUCCESS) { apr_brigade_cleanup(bbout); return rv; } copy = APR_BUCKET_NEXT(copy); if (copy != APR_BRIGADE_SENTINEL(bbout)) { APR_BUCKET_REMOVE(copy); apr_bucket_destroy(copy); } } break; } e = APR_BUCKET_NEXT(e); } AP_DEBUG_ASSERT(APR_SUCCESS == apr_brigade_length(bbout, 1, &pofft)); pos = (apr_uint64_t)pofft; AP_DEBUG_ASSERT(pos == end64 - start64 + 1); return APR_SUCCESS; }
static apr_status_t sendfile_nonblocking(apr_socket_t *s, apr_bucket *bucket, apr_size_t *cumulative_bytes_written, conn_rec *c) { apr_status_t rv = APR_SUCCESS; apr_bucket_file *file_bucket; apr_file_t *fd; apr_size_t file_length; apr_off_t file_offset; apr_size_t bytes_written = 0; if (!APR_BUCKET_IS_FILE(bucket)) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, c->base_server, APLOGNO(00006) "core_filter: sendfile_nonblocking: " "this should never happen"); return APR_EGENERAL; } file_bucket = (apr_bucket_file *)(bucket->data); fd = file_bucket->fd; file_length = bucket->length; file_offset = bucket->start; if (bytes_written < file_length) { apr_size_t n = file_length - bytes_written; apr_status_t arv; apr_interval_time_t old_timeout; arv = apr_socket_timeout_get(s, &old_timeout); if (arv != APR_SUCCESS) { return arv; } arv = apr_socket_timeout_set(s, 0); if (arv != APR_SUCCESS) { return arv; } rv = apr_socket_sendfile(s, fd, NULL, &file_offset, &n, 0); if (rv == APR_SUCCESS) { bytes_written += n; file_offset += n; } arv = apr_socket_timeout_set(s, old_timeout); if ((arv != APR_SUCCESS) && (rv == APR_SUCCESS)) { rv = arv; } } if ((ap__logio_add_bytes_out != NULL) && (bytes_written > 0)) { ap__logio_add_bytes_out(c, bytes_written); } *cumulative_bytes_written += bytes_written; if ((bytes_written < file_length) && (bytes_written > 0)) { apr_bucket_split(bucket, bytes_written); APR_BUCKET_REMOVE(bucket); apr_bucket_destroy(bucket); } else if (bytes_written == file_length) { APR_BUCKET_REMOVE(bucket); apr_bucket_destroy(bucket); } return rv; }
static apr_status_t writev_nonblocking(apr_socket_t *s, struct iovec *vec, apr_size_t nvec, apr_bucket_brigade *bb, apr_size_t *cumulative_bytes_written, conn_rec *c) { apr_status_t rv = APR_SUCCESS, arv; apr_size_t bytes_written = 0, bytes_to_write = 0; apr_size_t i, offset; apr_interval_time_t old_timeout; arv = apr_socket_timeout_get(s, &old_timeout); if (arv != APR_SUCCESS) { return arv; } arv = apr_socket_timeout_set(s, 0); if (arv != APR_SUCCESS) { return arv; } for (i = 0; i < nvec; i++) { bytes_to_write += vec[i].iov_len; } offset = 0; while (bytes_written < bytes_to_write) { apr_size_t n = 0; rv = apr_socket_sendv(s, vec + offset, nvec - offset, &n); if (n > 0) { bytes_written += n; for (i = offset; i < nvec; ) { apr_bucket *bucket = APR_BRIGADE_FIRST(bb); if (APR_BUCKET_IS_METADATA(bucket)) { APR_BUCKET_REMOVE(bucket); apr_bucket_destroy(bucket); } else if (n >= vec[i].iov_len) { APR_BUCKET_REMOVE(bucket); apr_bucket_destroy(bucket); offset++; n -= vec[i++].iov_len; } else { apr_bucket_split(bucket, n); APR_BUCKET_REMOVE(bucket); apr_bucket_destroy(bucket); vec[i].iov_len -= n; vec[i].iov_base = (char *) vec[i].iov_base + n; break; } } } if (rv != APR_SUCCESS) { break; } } if ((ap__logio_add_bytes_out != NULL) && (bytes_written > 0)) { ap__logio_add_bytes_out(c, bytes_written); } *cumulative_bytes_written += bytes_written; arv = apr_socket_timeout_set(s, old_timeout); if ((arv != APR_SUCCESS) && (rv == APR_SUCCESS)) { return arv; } else { return rv; } }