1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "httpd.h" 18#include "http_request.h" 19#include "http_protocol.h" 20#include "scoreboard.h" 21 22static apr_status_t eor_bucket_cleanup(void *data) 23{ 24 apr_bucket *b = (apr_bucket *)data; 25 request_rec *r = (request_rec *)b->data; 26 27 if (r != NULL) { 28 /* 29 * If eor_bucket_destroy is called after us, this prevents 30 * eor_bucket_destroy from trying to destroy the pool again. 31 */ 32 b->data = NULL; 33 /* Update child status and log the transaction */ 34 ap_update_child_status(r->connection->sbh, SERVER_BUSY_LOG, r); 35 ap_run_log_transaction(r); 36 if (ap_extended_status) { 37 ap_increment_counts(r->connection->sbh, r); 38 } 39 } 40 return APR_SUCCESS; 41} 42 43static apr_status_t eor_bucket_read(apr_bucket *b, const char **str, 44 apr_size_t *len, apr_read_type_e block) 45{ 46 *str = NULL; 47 *len = 0; 48 return APR_SUCCESS; 49} 50 51AP_DECLARE(apr_bucket *) ap_bucket_eor_make(apr_bucket *b, request_rec *r) 52{ 53 b->length = 0; 54 b->start = 0; 55 b->data = r; 56 b->type = &ap_bucket_type_eor; 57 58 return b; 59} 60 61AP_DECLARE(apr_bucket *) ap_bucket_eor_create(apr_bucket_alloc_t *list, 62 request_rec *r) 63{ 64 apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); 65 66 APR_BUCKET_INIT(b); 67 b->free = apr_bucket_free; 68 b->list = list; 69 if (r) { 70 /* 71 * Register a cleanup for the request pool as the eor bucket could 72 * have been allocated from a different pool then the request pool 73 * e.g. the parent pool of the request pool. In this case 74 * eor_bucket_destroy might be called at a point of time when the 75 * request pool had been already destroyed. 76 * We need to use a pre-cleanup here because a module may create a 77 * sub-pool which is still needed during the log_transaction hook. 78 */ 79 apr_pool_pre_cleanup_register(r->pool, (void *)b, eor_bucket_cleanup); 80 } 81 return ap_bucket_eor_make(b, r); 82} 83 84static void eor_bucket_destroy(void *data) 85{ 86 request_rec *r = (request_rec *)data; 87 88 if (r) { 89 /* eor_bucket_cleanup will be called when the pool gets destroyed */ 90 apr_pool_destroy(r->pool); 91 } 92} 93 94AP_DECLARE_DATA const apr_bucket_type_t ap_bucket_type_eor = { 95 "EOR", 5, APR_BUCKET_METADATA, 96 eor_bucket_destroy, 97 eor_bucket_read, 98 apr_bucket_setaside_noop, 99 apr_bucket_split_notimpl, 100 apr_bucket_simple_copy 101}; 102 103