@@ -13,9 +13,13 @@ static char errbuf[1024];
1313
1414static void redirectionio_register_hooks (apr_pool_t * p );
1515
16+ static void ap_headers_insert_output_filter (request_rec * r );
17+
1618static int redirectionio_redirect_handler (request_rec * r );
1719static int redirectionio_log_handler (request_rec * r );
1820
21+ static apr_status_t redirectionio_filter_match_on_response (ap_filter_t * f , apr_bucket_brigade * b );
22+
1923static apr_status_t redirectionio_create_connection (redirectionio_connection * conn , redirectionio_config * config , apr_pool_t * pool );
2024static redirectionio_connection * redirectionio_acquire_connection (redirectionio_config * config , apr_pool_t * pool );
2125static apr_status_t redirectionio_release_connection (redirectionio_connection * conn , redirectionio_config * config , apr_pool_t * pool );
@@ -54,6 +58,29 @@ module AP_MODULE_DECLARE_DATA redirectionio_module = {
5458static void redirectionio_register_hooks (apr_pool_t * p ) {
5559 ap_hook_handler (redirectionio_redirect_handler , NULL , NULL , APR_HOOK_FIRST );
5660 ap_hook_log_transaction (redirectionio_log_handler , NULL , NULL , APR_HOOK_MIDDLE );
61+
62+ ap_hook_insert_filter (ap_headers_insert_output_filter , NULL , NULL , APR_HOOK_LAST );
63+ ap_hook_insert_error_filter (ap_headers_insert_output_filter , NULL , NULL , APR_HOOK_LAST );
64+ ap_register_output_filter ("redirectionio_redirect_filter" , redirectionio_filter_match_on_response , NULL , AP_FTYPE_CONTENT_SET );
65+ }
66+
67+ static void ap_headers_insert_output_filter (request_rec * r ) {
68+ redirectionio_config * config = (redirectionio_config * ) ap_get_module_config (r -> per_dir_config , & redirectionio_module );
69+ redirectionio_context * ctx = ap_get_module_config (r -> request_config , & redirectionio_module );
70+
71+ if (config -> enable != 1 ) {
72+ return ;
73+ }
74+
75+ if (ctx == NULL || ctx -> status == 0 || ctx -> match_on_response_status == 0 || ctx -> is_redirected ) {
76+ return ;
77+ }
78+
79+ if (r -> status != ctx -> match_on_response_status ) {
80+ return ;
81+ }
82+
83+ ap_add_output_filter ("redirectionio_redirect_filter" , ctx , r , r -> connection );
5784}
5885
5986static int redirectionio_redirect_handler (request_rec * r ) {
@@ -72,6 +99,10 @@ static int redirectionio_redirect_handler(request_rec *r) {
7299 return DECLINED ;
73100 }
74101
102+ context -> status = 0 ;
103+ context -> match_on_response_status = 0 ;
104+ context -> is_redirected = 0 ;
105+
75106 ap_set_module_config (r -> request_config , & redirectionio_module , context );
76107 redirectionio_connection * conn = redirectionio_acquire_connection (config , r -> pool );
77108
@@ -86,10 +117,14 @@ static int redirectionio_redirect_handler(request_rec *r) {
86117 return DECLINED ;
87118 }
88119
89- // No match
120+ redirectionio_release_connection (conn , config , r -> pool );
121+
122+ // No match here
90123 if (context -> status == 0 ) {
91- redirectionio_release_connection (conn , config , r -> pool );
124+ return DECLINED ;
125+ }
92126
127+ if (context -> match_on_response_status > 0 ) {
93128 return DECLINED ;
94129 }
95130
@@ -98,12 +133,27 @@ static int redirectionio_redirect_handler(request_rec *r) {
98133 }
99134
100135 r -> status = context -> status ;
101-
102- redirectionio_release_connection (conn , config , r -> pool );
136+ context -> is_redirected = 1 ;
103137
104138 return context -> status ;
105139}
106140
141+ static apr_status_t redirectionio_filter_match_on_response (ap_filter_t * f , apr_bucket_brigade * bb ) {
142+ redirectionio_context * ctx = (redirectionio_context * )f -> ctx ;
143+
144+ if (ctx -> status != 410 ) {
145+ apr_table_setn (f -> r -> headers_out , "Location" , ctx -> target );
146+ }
147+
148+ f -> r -> status = ctx -> status ;
149+ ctx -> is_redirected = 1 ;
150+
151+ /* remove ourselves from the filter chain */
152+ ap_remove_output_filter (f );
153+
154+ return ap_pass_brigade (f -> next , bb );
155+ }
156+
107157static int redirectionio_log_handler (request_rec * r ) {
108158 redirectionio_config * config = (redirectionio_config * ) ap_get_module_config (r -> per_dir_config , & redirectionio_module );
109159
0 commit comments