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 "apr_buckets.h" 18 19static apr_status_t pipe_bucket_read(apr_bucket *a, const char **str, 20 apr_size_t *len, apr_read_type_e block) 21{ 22 apr_file_t *p = a->data; 23 char *buf; 24 apr_status_t rv; 25 apr_interval_time_t timeout; 26 27 if (block == APR_NONBLOCK_READ) { 28 apr_file_pipe_timeout_get(p, &timeout); 29 apr_file_pipe_timeout_set(p, 0); 30 } 31 32 *str = NULL; 33 *len = APR_BUCKET_BUFF_SIZE; 34 buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */ 35 36 rv = apr_file_read(p, buf, len); 37 38 if (block == APR_NONBLOCK_READ) { 39 apr_file_pipe_timeout_set(p, timeout); 40 } 41 42 if (rv != APR_SUCCESS && rv != APR_EOF) { 43 apr_bucket_free(buf); 44 return rv; 45 } 46 /* 47 * If there's more to read we have to keep the rest of the pipe 48 * for later. Otherwise, we'll close the pipe. 49 * XXX: Note that more complicated bucket types that 50 * refer to data not in memory and must therefore have a read() 51 * function similar to this one should be wary of copying this 52 * code because if they have a destroy function they probably 53 * want to migrate the bucket's subordinate structure from the 54 * old bucket to a raw new one and adjust it as appropriate, 55 * rather than destroying the old one and creating a completely 56 * new bucket. 57 */ 58 if (*len > 0) { 59 apr_bucket_heap *h; 60 /* Change the current bucket to refer to what we read */ 61 a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free); 62 h = a->data; 63 h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */ 64 *str = buf; 65 APR_BUCKET_INSERT_AFTER(a, apr_bucket_pipe_create(p, a->list)); 66 } 67 else { 68 apr_bucket_free(buf); 69 a = apr_bucket_immortal_make(a, "", 0); 70 *str = a->data; 71 if (rv == APR_EOF) { 72 apr_file_close(p); 73 } 74 } 75 return APR_SUCCESS; 76} 77 78APU_DECLARE(apr_bucket *) apr_bucket_pipe_make(apr_bucket *b, apr_file_t *p) 79{ 80 /* 81 * A pipe is closed when the end is reached in pipe_bucket_read(). If 82 * the pipe isn't read to the end (e.g., error path), the pipe will be 83 * closed when its pool goes away. 84 * 85 * Note that typically the pipe is allocated from the request pool 86 * so it will disappear when the request is finished. However the 87 * core filter may decide to set aside the tail end of a CGI 88 * response if the connection is pipelined. This turns out not to 89 * be a problem because the core will have read to the end of the 90 * stream so the bucket(s) that it sets aside will be the heap 91 * buckets created by pipe_bucket_read() above. 92 */ 93 b->type = &apr_bucket_type_pipe; 94 b->length = (apr_size_t)(-1); 95 b->start = -1; 96 b->data = p; 97 98 return b; 99} 100 101APU_DECLARE(apr_bucket *) apr_bucket_pipe_create(apr_file_t *p, 102 apr_bucket_alloc_t *list) 103{ 104 apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); 105 106 APR_BUCKET_INIT(b); 107 b->free = apr_bucket_free; 108 b->list = list; 109 return apr_bucket_pipe_make(b, p); 110} 111 112APU_DECLARE_DATA const apr_bucket_type_t apr_bucket_type_pipe = { 113 "PIPE", 5, APR_BUCKET_DATA, 114 apr_bucket_destroy_noop, 115 pipe_bucket_read, 116 apr_bucket_setaside_notimpl, 117 apr_bucket_split_notimpl, 118 apr_bucket_copy_notimpl 119}; 120