Apache HTTPD
mod_reflector.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#include "apr_strings.h"
17#include "apr_tables.h"
18
19#include "httpd.h"
20#include "http_config.h"
21#include "http_core.h"
22#include "http_log.h"
23#include "http_protocol.h"
24#include "http_request.h"
25#include "mod_core.h"
26
27module AP_MODULE_DECLARE_DATA reflector_module;
28
29typedef struct {
32
33static int header_do(void *dummy, const char *key, const char *value)
34{
36 const char *payload;
37
39 if (payload) {
41 }
42
43 return 1;
44}
45
47{
49 reflector_cfg *conf;
51
52 if (strcmp(r->handler, "reflector")) {
53 return DECLINED;
54 }
55
57 &reflector_module);
58
59 ap_allow_methods(r, 1, "POST", "OPTIONS", NULL);
60
61 if (r->method_number == M_OPTIONS) {
62 return ap_send_http_options(r);
63 }
64
65 else if (r->method_number == M_POST) {
66 const char *content_length, *content_type;
67 int seen_eos;
68
69 /*
70 * Sometimes we'll get in a state where the input handling has
71 * detected an error where we want to drop the connection, so if
72 * that's the case, don't read the data as that is what we're trying
73 * to avoid.
74 *
75 * This function is also a no-op on a subrequest.
76 */
79 return OK;
80 }
81
82 /* copy headers from in to out if configured */
84
85 /* last modified defaults to now, unless otherwise set on the way in */
86 if (!apr_table_get(r->headers_out, "Last-Modified")) {
89 }
91
92 /* reflect the content length, if present */
93 if ((content_length = apr_table_get(r->headers_in, "Content-Length"))) {
95
96 if (!ap_parse_strict_length(&clen, content_length)) {
98 "reflector_handler: invalid content-length '%s'",
99 content_length);
100 return HTTP_BAD_REQUEST;
101 }
102
104 }
105
106 /* reflect the content type, if present */
107 if ((content_type = apr_table_get(r->headers_in, "Content-Type"))) {
108
110
111 }
112
115
116 seen_eos = 0;
117 do {
118 apr_bucket *bucket;
119
122
123 if (status != APR_SUCCESS) {
126 }
127
128 for (bucket = APR_BRIGADE_FIRST(bbin);
129 bucket != APR_BRIGADE_SENTINEL(bbin);
130 bucket = APR_BUCKET_NEXT(bucket)) {
131 const char *data;
133
134 if (APR_BUCKET_IS_EOS(bucket)) {
135 seen_eos = 1;
136 break;
137 }
138
139 /* These are metadata buckets. */
140 if (bucket->length == 0) {
141 continue;
142 }
143
144 /*
145 * We MUST read because in case we have an unknown-length
146 * bucket or one that morphs, we want to exhaust it.
147 */
149 if (status != APR_SUCCESS) {
151 return HTTP_BAD_REQUEST;
152 }
153
155
157 if (status != APR_SUCCESS) {
158 /* no way to know what type of error occurred */
160 "reflector_handler: ap_pass_brigade returned %i",
161 status);
162 return AP_FILTER_ERROR;
163 }
164
165 }
166
168
169 } while (!seen_eos);
170
171 return OK;
172
173 }
174
175 else {
177 }
178
179}
180
182{
183 reflector_cfg *conf = apr_pcalloc(p, sizeof(reflector_cfg));
184
185 conf->headers = apr_table_make(p, 8);
186
187 return conf;
188}
189
190static void *merge_reflector_dir_config(apr_pool_t * p, void *basev, void *addv)
191{
193 sizeof(reflector_cfg));
196
197 new->headers = apr_table_overlay(p, add->headers, base->headers);
198
199 return new;
200}
201
202static const char *reflector_header(cmd_parms * cmd, void *dummy, const char *in,
203 const char *out)
204{
206
207 apr_table_addn(cfg->headers, in, out ? out : in);
208
209 return NULL;
210}
211
216
217static const command_rec reflector_cmds[] = {
218 AP_INIT_TAKE12("ReflectorHeader", reflector_header, NULL, OR_OPTIONS,
219 "Header to reflect back in the response, with an optional new name."),
220 {NULL}
221};
222
227 NULL,
228 NULL,
231};
const char apr_size_t len
Definition ap_regex.h:187
apr_size_t const unsigned char unsigned int unsigned int d
Definition apr_siphash.h:72
APR Strings library.
APR Table library.
#define ap_get_module_config(v, m)
#define AP_DECLARE_MODULE(foo)
ap_conf_vector_t * base
void ap_hook_handler(ap_HOOK_handler_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:170
#define AP_INIT_TAKE12(directive, func, mconfig, where, help)
request_rec * r
#define HUGE_STRING_LEN
Definition httpd.h:303
#define AP_FILTER_ERROR
Definition httpd.h:473
#define DECLINED
Definition httpd.h:457
#define OK
Definition httpd.h:456
apr_status_t ap_pass_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket)
apr_status_t ap_get_brigade(ap_filter_t *filter, apr_bucket_brigade *bucket, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
#define APLOGNO(n)
Definition http_log.h:117
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_MARK
Definition http_log.h:283
#define APLOG_DEBUG
Definition http_log.h:71
void ap_set_accept_ranges(request_rec *r)
int ap_map_http_request_error(apr_status_t rv, int status)
void ap_set_content_length(request_rec *r, apr_off_t length)
Definition protocol.c:160
void ap_set_last_modified(request_rec *r)
Definition protocol.c:2280
void ap_set_content_type(request_rec *r, const char *ct)
void ap_allow_methods(request_rec *r, int reset,...)
void ap_update_mtime(request_rec *r, apr_time_t dependency_mtime)
Definition request.c:2557
void * dummy
Definition http_vhost.h:62
#define APR_BUCKET_NEXT(e)
#define APR_BRIGADE_SENTINEL(b)
#define APR_BUCKET_IS_EOS(e)
#define APR_BRIGADE_FIRST(b)
#define apr_bucket_read(e, str, len, block)
@ APR_BLOCK_READ
Definition apr_buckets.h:58
#define APR_HOOK_MIDDLE
Definition apr_hooks.h:303
#define OR_OPTIONS
#define HTTP_BAD_REQUEST
Definition httpd.h:508
#define HTTP_METHOD_NOT_ALLOWED
Definition httpd.h:513
#define ap_status_drops_connection(x)
Definition httpd.h:563
int ap_send_http_options(request_rec *r)
#define M_OPTIONS
Definition httpd.h:597
#define M_POST
Definition httpd.h:594
#define STANDARD20_MODULE_STUFF
int ap_parse_strict_length(apr_off_t *len, const char *str)
Definition util.c:2683
@ AP_CONN_CLOSE
Definition httpd.h:1145
apr_size_t size
const char * value
Definition apr_env.h:51
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
const char * key
void * data
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
apr_int32_t in
apr_cmdtype_e cmd
int int status
Apache Configuration.
CORE HTTP Daemon.
Apache Logging library.
HTTP protocol handling.
Apache Request library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
mod_core private header file
static apr_file_t * out
Definition mod_info.c:85
static void * create_reflector_dir_config(apr_pool_t *p, char *d)
static int header_do(void *dummy, const char *key, const char *value)
static void reflector_hooks(apr_pool_t *p)
static void * merge_reflector_dir_config(apr_pool_t *p, void *basev, void *addv)
static const command_rec reflector_cmds[]
static int reflector_handler(request_rec *r)
static const char * reflector_header(cmd_parms *cmd, void *dummy, const char *in, const char *out)
return NULL
Definition mod_so.c:359
apr_size_t length
ap_conn_keepalive_e keepalive
Definition httpd.h:1223
struct apr_bucket_alloc_t * bucket_alloc
Definition httpd.h:1201
apr_table_t * headers
A structure that represents the current request.
Definition httpd.h:845
int status
Definition httpd.h:891
struct ap_filter_t * output_filters
Definition httpd.h:1070
const char * handler
Definition httpd.h:994
int method_number
Definition httpd.h:898
apr_pool_t * pool
Definition httpd.h:847
conn_rec * connection
Definition httpd.h:849
struct ap_filter_t * input_filters
Definition httpd.h:1072
apr_table_t * headers_in
Definition httpd.h:976
request_rec * main
Definition httpd.h:860
struct ap_conf_vector_t * per_dir_config
Definition httpd.h:1047
apr_table_t * headers_out
Definition httpd.h:978
@ AP_MODE_READBYTES
Definition util_filter.h:43