Skip to content

Commit 8f8ca3a

Browse files
committed
Update apache module with libredirectionio
1 parent a23f20f commit 8f8ca3a

File tree

4 files changed

+99
-323
lines changed

4 files changed

+99
-323
lines changed

src/mod_redirectionio.c

Lines changed: 53 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ static int redirectionio_match_handler(request_rec *r);
2020
static int redirectionio_redirect_handler(request_rec *r);
2121
static int redirectionio_log_handler(request_rec *r);
2222

23+
static int redirectionio_redirect_handler_for_status_code(request_rec *r, uint16_t status_code);
24+
2325
static apr_status_t redirectionio_filter_match_on_response(ap_filter_t *f, apr_bucket_brigade *b);
2426
static apr_status_t redirectionio_filter_header_filtering(ap_filter_t *f, apr_bucket_brigade *b);
2527
static apr_status_t redirectionio_filter_body_filtering(ap_filter_t *f, apr_bucket_brigade *b);
@@ -124,14 +126,10 @@ static int redirectionio_match_handler(request_rec *r) {
124126
return DECLINED;
125127
}
126128

127-
ctx->matched_rule_id = NULL;
128-
ctx->target = NULL;
129-
ctx->status = 0;
130-
ctx->match_on_response_status = 0;
129+
ctx->matched_rule_str = NULL;
130+
ctx->matched_rule = NULL;
131+
ctx->filter_id = NULL;
131132
ctx->is_redirected = 0;
132-
ctx->should_filter_body = 0;
133-
ctx->should_filter_headers = 0;
134-
ctx->body_filter_conn = NULL;
135133

136134
ap_set_module_config(r->request_config, &redirectionio_module, ctx);
137135
redirectionio_connection* conn = redirectionio_acquire_connection(config, r->pool);
@@ -169,7 +167,9 @@ static void ap_headers_insert_output_filter(request_rec *r) {
169167
ap_add_output_filter("redirectionio_body_filter", ctx, r, r->connection);
170168
}
171169

172-
static int redirectionio_redirect_handler(request_rec *r) {
170+
static int redirectionio_redirect_handler_for_status_code(request_rec *r, uint16_t status_code) {
171+
char *redirect_str, *location_str;
172+
cJSON *redirect, *location, *status;
173173
redirectionio_config *config = (redirectionio_config*) ap_get_module_config(r->per_dir_config, &redirectionio_module);
174174

175175
// Not enabled
@@ -184,42 +184,47 @@ static int redirectionio_redirect_handler(request_rec *r) {
184184
}
185185

186186
// No match here
187-
if (ctx->status == 0 || ctx->is_redirected == 1) {
187+
if (ctx->matched_rule_str == NULL || ctx->is_redirected == 1) {
188188
return DECLINED;
189189
}
190190

191-
if (ctx->match_on_response_status > 0) {
192-
return DECLINED;
193-
}
191+
redirect_str = (char *)redirectionio_get_redirect(ctx->matched_rule_str, r->unparsed_uri, status_code);
194192

195-
if (ctx->status != 410) {
196-
apr_table_setn(r->headers_out, "Location", ctx->target);
193+
if (redirect_str == NULL) {
194+
return DECLINED;
197195
}
198196

199-
r->status = ctx->status;
200-
ctx->is_redirected = 1;
201-
202-
return ctx->status;
203-
}
204-
205-
static apr_status_t redirectionio_filter_match_on_response(ap_filter_t *f, apr_bucket_brigade *bb) {
206-
redirectionio_context *ctx = (redirectionio_context *)f->ctx;
197+
redirect = cJSON_Parse(redirect_str);
207198

208-
if (ctx == NULL) {
209-
return ap_pass_brigade(f->next, bb);
199+
if (redirect == NULL) {
200+
return DECLINED;
210201
}
211202

212-
if (ctx->is_redirected || ctx->status == 0 || (ctx->match_on_response_status > 0 && ctx->match_on_response_status != f->r->status)) {
213-
return ap_pass_brigade(f->next, bb);
203+
status = cJSON_GetObjectItem(redirect, "status_code");
204+
location = cJSON_GetObjectItem(redirect, "location");
205+
206+
if (status == NULL || location == NULL) {
207+
return DECLINED;
214208
}
215209

216-
if (ctx->status != 410) {
217-
apr_table_setn(f->r->headers_out, "Location", ctx->target);
210+
if (status->valueint != 410) {
211+
location_str = apr_pstrdup(r->pool, location->valuestring);
212+
apr_table_setn(r->headers_out, "Location", location_str);
218213
}
219214

220-
f->r->status = ctx->status;
215+
r->status = status->valueint;
221216
ctx->is_redirected = 1;
222217

218+
return r->status;
219+
}
220+
221+
static int redirectionio_redirect_handler(request_rec *r) {
222+
return redirectionio_redirect_handler_for_status_code(r, 0);
223+
}
224+
225+
static apr_status_t redirectionio_filter_match_on_response(ap_filter_t *f, apr_bucket_brigade *bb) {
226+
redirectionio_redirect_handler_for_status_code(f->r, f->r->status);
227+
223228
/* remove ourselves from the filter chain */
224229
ap_remove_output_filter(f);
225230

@@ -228,66 +233,41 @@ static apr_status_t redirectionio_filter_match_on_response(ap_filter_t *f, apr_b
228233

229234
static apr_status_t redirectionio_filter_header_filtering(ap_filter_t *f, apr_bucket_brigade *bb) {
230235
redirectionio_context *ctx = (redirectionio_context *)f->ctx;
231-
redirectionio_config *config = (redirectionio_config*) ap_get_module_config(f->r->per_dir_config, &redirectionio_module);
232236

233237
if (ctx == NULL) {
234238
return ap_pass_brigade(f->next, bb);
235239
}
236240

237-
if (ctx->should_filter_headers == 0 || (ctx->is_redirected != 1 && ctx->match_on_response_status > 0 && ctx->match_on_response_status != f->r->status)) {
241+
if (ctx->matched_rule_str == NULL) {
238242
return ap_pass_brigade(f->next, bb);
239243
}
240244

245+
redirectionio_protocol_send_filter_headers(ctx, f->r);
241246
ap_remove_output_filter(f);
242247

243-
// Get connection
244-
redirectionio_connection* conn = redirectionio_acquire_connection(config, f->r->pool);
245-
246-
if (conn == NULL) {
247-
return ap_pass_brigade(f->next, bb);
248-
}
249-
250-
// Send headers
251-
if (redirectionio_protocol_send_filter_headers(conn, ctx, f->r, config->project_key) != APR_SUCCESS) {
252-
redirectionio_invalidate_connection(conn, config, f->r->pool);
253-
254-
return ap_pass_brigade(f->next, bb);
255-
}
256-
257-
redirectionio_release_connection(conn, config, f->r->pool);
258-
259248
return ap_pass_brigade(f->next, bb);
260249
}
261250

262251
static apr_status_t redirectionio_filter_body_filtering(ap_filter_t *f, apr_bucket_brigade *bb) {
263252
redirectionio_context *ctx = (redirectionio_context *)f->ctx;
264-
redirectionio_config *config = (redirectionio_config*) ap_get_module_config(f->r->per_dir_config, &redirectionio_module);
265253
apr_bucket *b, *b_new;
266254
apr_bucket_brigade *bb_new;
267-
const char *input, *output;
255+
const char *input, *output, *input_str;
268256
int64_t input_size, output_size;
269257
apr_status_t rv;
270258

271259
if (ctx == NULL) {
272260
return ap_pass_brigade(f->next, bb);
273261
}
274262

275-
if (ctx->should_filter_body == 0 || (ctx->is_redirected != 1 && ctx->match_on_response_status > 0 && ctx->match_on_response_status != f->r->status)) {
263+
if (ctx->matched_rule_str == NULL) {
276264
return ap_pass_brigade(f->next, bb);
277265
}
278266

279-
// If first -> remove content_length, get_connection, init filtering command
280-
if (ctx->body_filter_conn == NULL) {
281-
ctx->body_filter_conn = redirectionio_acquire_connection(config, f->r->pool);
282-
283-
if (ctx->body_filter_conn == NULL) {
284-
ap_remove_output_filter(f);
285-
286-
return ap_pass_brigade(f->next, bb);
287-
}
267+
if (ctx->filter_id == NULL) {
268+
ctx->filter_id = (char *)redirectionio_create_body_filter(ctx->matched_rule_str);
288269

289-
if (redirectionio_protocol_send_filter_body_init(ctx->body_filter_conn, ctx, f->r, config->project_key) != APR_SUCCESS) {
290-
redirectionio_invalidate_connection(ctx->body_filter_conn, config, f->r->pool);
270+
if (ctx->filter_id == NULL) {
291271
ap_remove_output_filter(f);
292272

293273
return ap_pass_brigade(f->next, bb);
@@ -310,29 +290,32 @@ static apr_status_t redirectionio_filter_body_filtering(ap_filter_t *f, apr_buck
310290
rv = apr_bucket_read(b, &input, (apr_size_t *)&input_size, APR_BLOCK_READ);
311291

312292
if (rv != APR_SUCCESS) {
313-
redirectionio_invalidate_connection(ctx->body_filter_conn, config, f->r->pool);
293+
free(ctx->filter_id);
294+
ctx->filter_id = NULL;
314295
ap_remove_output_filter(f);
315296

316297
return ap_pass_brigade(f->next, bb);
317298
}
318299

319300
// Send bucket
320301
if (input_size > 0) {
321-
rv = redirectionio_protocol_send_filter_body_chunk(ctx->body_filter_conn, input, input_size, &output, &output_size, f->r->pool);
302+
input_str = strndup(input, input_size);
303+
output = redirectionio_body_filter(ctx->filter_id, input_str);
304+
free((char *)input_str);
322305

323-
if (rv != APR_SUCCESS) {
324-
redirectionio_invalidate_connection(ctx->body_filter_conn, config, f->r->pool);
306+
if (output == NULL) {
325307
ap_remove_output_filter(f);
326308

327309
return ap_pass_brigade(f->next, bb);
328310
}
329311

312+
output_size = strlen(output);
313+
330314
// Create a new one
331315
if (output_size > 0) {
332316
b_new = apr_bucket_transient_create(output, output_size, f->r->connection->bucket_alloc);
333317

334318
if (b_new == NULL) {
335-
redirectionio_invalidate_connection(ctx->body_filter_conn, config, f->r->pool);
336319
ap_remove_output_filter(f);
337320

338321
return ap_pass_brigade(f->next, bb);
@@ -344,22 +327,21 @@ static apr_status_t redirectionio_filter_body_filtering(ap_filter_t *f, apr_buck
344327
}
345328

346329
if (APR_BUCKET_IS_EOS(b)) {
347-
// Send termination to the connection and wait for it to return us the last data
348-
rv = redirectionio_protocol_send_filter_body_finish(ctx->body_filter_conn, &output, &output_size, f->r->pool);
330+
output = redirectionio_body_filter_end(ctx->filter_id);
349331

350-
if (rv != APR_SUCCESS) {
351-
redirectionio_invalidate_connection(ctx->body_filter_conn, config, f->r->pool);
332+
if (output == NULL) {
352333
ap_remove_output_filter(f);
353334

354335
return ap_pass_brigade(f->next, bb);
355336
}
356337

338+
output_size = strlen(output);
339+
357340
if (output_size > 0) {
358341
// Create a new one
359342
b_new = apr_bucket_transient_create(output, output_size, f->r->connection->bucket_alloc);
360343

361344
if (b_new == NULL) {
362-
redirectionio_invalidate_connection(ctx->body_filter_conn, config, f->r->pool);
363345
ap_remove_output_filter(f);
364346

365347
return ap_pass_brigade(f->next, bb);
@@ -373,17 +355,13 @@ static apr_status_t redirectionio_filter_body_filtering(ap_filter_t *f, apr_buck
373355
b_new = apr_bucket_eos_create(f->r->connection->bucket_alloc);
374356

375357
if (b_new == NULL) {
376-
redirectionio_invalidate_connection(ctx->body_filter_conn, config, f->r->pool);
377358
ap_remove_output_filter(f);
378359

379360
return ap_pass_brigade(f->next, bb);
380361
}
381362

382363
APR_BRIGADE_INSERT_TAIL(bb_new, b_new);
383364

384-
// Release connection
385-
redirectionio_release_connection(ctx->body_filter_conn, config, f->r->pool);
386-
387365
// Remove filter
388366
ap_remove_output_filter(f);
389367

src/mod_redirectionio.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "apr_network_io.h"
55
#include "apr_reslist.h"
66
#include "redirectionio.h"
7+
#include "json.h"
78

89
#ifndef APR_UNIX
910
#if defined (AF_UNIX)
@@ -50,14 +51,10 @@ typedef struct {
5051
} redirectionio_connection;
5152

5253
typedef struct {
53-
char *matched_rule_id;
54-
char *target;
55-
int status;
56-
int match_on_response_status;
57-
int is_redirected;
58-
int should_filter_headers;
59-
int should_filter_body;
60-
redirectionio_connection *body_filter_conn;
54+
char *matched_rule_str;
55+
cJSON *matched_rule;
56+
char *filter_id;
57+
int is_redirected;
6158
} redirectionio_context;
6259

6360
#endif

0 commit comments

Comments
 (0)