Apache HTTPD
mod_bucketeer.c
Go to the documentation of this file.
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/*
18 * mod_bucketeer.c: split buckets whenever we find a control-char
19 *
20 * Written by Ian Holsman
21 *
22 */
23
24#include "httpd.h"
25#include "http_config.h"
26#include "http_log.h"
27#include "apr_strings.h"
28#include "apr_general.h"
29#include "util_filter.h"
30#include "apr_buckets.h"
31#include "http_request.h"
32#include "http_protocol.h"
33
34static const char bucketeerFilterName[] = "BUCKETEER";
35module AP_MODULE_DECLARE_DATA bucketeer_module;
36
43
44
46{
48
49 c->bucketdelimiter = 0x02; /* ^B */
50 c->passdelimiter = 0x10; /* ^P */
51 c->flushdelimiter = 0x06; /* ^F */
52
53 return c;
54}
55
60
63{
65 request_rec *r = f->r;
66 bucketeer_ctx_t *ctx = f->ctx;
68
69 c = ap_get_module_config(r->server->module_config, &bucketeer_module);
70
71 /* If have a context, it means we've done this before successfully. */
72 if (!ctx) {
73 if (!r->content_type || strncmp(r->content_type, "text/", 5)) {
75 return ap_pass_brigade(f->next, bb);
76 }
77
78 /* We're cool with filtering this. */
79 ctx = f->ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
80 ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
81 apr_table_unset(f->r->headers_out, "Content-Length");
82 }
83
84 for (e = APR_BRIGADE_FIRST(bb);
87 {
88 const char *data;
90
91 if (APR_BUCKET_IS_EOS(e)) {
94
95 /* Okay, we've seen the EOS.
96 * Time to pass it along down the chain.
97 */
98 return ap_pass_brigade(f->next, ctx->bb);
99 }
100
101 if (APR_BUCKET_IS_FLUSH(e)) {
102 /*
103 * Ignore flush buckets for the moment..
104 * we decide what to stream
105 */
106 continue;
107 }
108
110 /* metadata bucket */
114 continue;
115 }
116
117 /* read */
119
120 if (len > 0) {
121 lastpos = 0;
122 for (i = 0; i < len; i++) {
123 if (data[i] == c->flushdelimiter ||
124 data[i] == c->bucketdelimiter ||
125 data[i] == c->passdelimiter) {
126 apr_bucket *p;
127 if (i - lastpos > 0) {
129 &data[lastpos],
130 i - lastpos),
131 i - lastpos,
132 f->r->pool,
133 f->c->bucket_alloc);
135 }
136 lastpos = i + 1;
137 if (data[i] == c->flushdelimiter) {
138 p = apr_bucket_flush_create(f->c->bucket_alloc);
140 }
141 if (data[i] == c->passdelimiter) {
142 apr_status_t rv;
143
144 rv = ap_pass_brigade(f->next, ctx->bb);
145 if (rv) {
146 return rv;
147 }
148 }
149 }
150 }
151 /* XXX: really should append this to the next 'real' bucket */
152 if (lastpos < i) {
153 apr_bucket *p;
155 &data[lastpos],
156 i - lastpos),
157 i - lastpos,
158 f->r->pool,
159 f->c->bucket_alloc);
160 lastpos = i;
162 }
163 }
164 }
165
166 return APR_SUCCESS;
167}
168
174
176 {NULL}
177};
178
181 NULL,
182 NULL,
184 NULL,
187};
const char apr_size_t len
Definition ap_regex.h:187
APR-UTIL Buckets/Bucket Brigades.
APR Miscellaneous library routines.
APR Strings library.
#define ap_get_module_config(v, m)
#define AP_DECLARE_MODULE(foo)
request_rec * r
apr_status_t ap_pass_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket)
ap_filter_rec_t * ap_register_output_filter(const char *name, ap_out_filter_func filter_func, ap_init_filter_func filter_init, ap_filter_type ftype)
void ap_remove_output_filter(ap_filter_t *f)
@ AP_FTYPE_RESOURCE
apr_file_t * f
#define APR_BUCKET_IS_FLUSH(e)
#define APR_BUCKET_REMOVE(e)
#define APR_BUCKET_IS_METADATA(e)
#define APR_BRIGADE_INSERT_TAIL(b, e)
#define APR_BUCKET_NEXT(e)
apr_bucket * e
#define APR_BRIGADE_SENTINEL(b)
#define APR_BUCKET_IS_EOS(e)
apr_brigade_flush void * ctx
#define apr_bucket_copy(e, c)
#define APR_BRIGADE_FIRST(b)
#define apr_bucket_read(e, str, len, block)
@ APR_BLOCK_READ
Definition apr_buckets.h:58
#define STANDARD20_MODULE_STUFF
apr_size_t size
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
apr_vformatter_buff_t * c
Definition apr_lib.h:175
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * s
Definition apr_strings.h:95
Apache Configuration.
Apache Logging library.
HTTP protocol handling.
Apache Request library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
static const char bucketeerFilterName[]
static void * create_bucketeer_server_config(apr_pool_t *p, server_rec *s)
static void register_hooks(apr_pool_t *p)
static apr_status_t bucketeer_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
static const command_rec bucketeer_filter_cmds[]
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
The representation of a filter chain.
apr_pool_t * pool
apr_bucket_brigade * bb
A structure that represents the current request.
Definition httpd.h:845
const char * content_type
Definition httpd.h:992
server_rec * server
Definition httpd.h:851
A structure to store information for each virtual server.
Definition httpd.h:1322
struct ap_conf_vector_t * module_config
Definition httpd.h:1341
Apache filter library.