@@ -17,10 +17,16 @@ static int redirectionio_redirect_handler(request_rec *r);
1717static int redirectionio_log_handler (request_rec * r );
1818
1919static apr_status_t redirectionio_create_connection (redirectionio_connection * conn , redirectionio_config * config , apr_pool_t * pool );
20+ static redirectionio_connection * redirectionio_acquire_connection (redirectionio_config * config , apr_pool_t * pool );
21+ static apr_status_t redirectionio_release_connection (redirectionio_connection * conn , redirectionio_config * config , apr_pool_t * pool );
2022
2123static void * create_redirectionio_dir_conf (apr_pool_t * pool , char * context );
2224static void * merge_redirectionio_dir_conf (apr_pool_t * pool , void * BASE , void * ADD );
2325
26+ static apr_status_t redirectionio_pool_construct (void * * rs , void * params , apr_pool_t * pool );
27+ static apr_status_t redirectionio_pool_destruct (void * resource , void * params , apr_pool_t * pool );
28+ static apr_status_t redirectionio_child_exit (void * resource );
29+
2430static const char * redirectionio_set_enable (cmd_parms * cmd , void * cfg , const char * arg );
2531static const char * redirectionio_set_project_key (cmd_parms * cmd , void * cfg , const char * arg );
2632static const char * redirectionio_set_logs_enable (cmd_parms * cmd , void * cfg , const char * arg );
@@ -66,27 +72,23 @@ static int redirectionio_redirect_handler(request_rec *r) {
6672 }
6773
6874 ap_set_module_config (r -> request_config , & redirectionio_module , context );
75+ redirectionio_connection * conn = redirectionio_acquire_connection (config , r -> pool );
6976
70- // Create connection
71- context -> conn = apr_palloc (r -> pool , sizeof (redirectionio_connection ));
72-
73- if (context -> conn == NULL ) {
74- ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , r , "Cannot create redirectionio context" );
75-
76- return DECLINED ;
77- }
78-
79- if (redirectionio_create_connection (context -> conn , config , r -> pool ) != APR_SUCCESS ) {
77+ if (conn == NULL ) {
8078 return DECLINED ;
8179 }
8280
8381 // Ask for redirection
84- if (redirectionio_protocol_match (context , r , config -> project_key ) != APR_SUCCESS ) {
82+ if (redirectionio_protocol_match (conn , context , r , config -> project_key ) != APR_SUCCESS ) {
83+ redirectionio_release_connection (conn , config , r -> pool );
84+
8585 return DECLINED ;
8686 }
8787
8888 // No match
8989 if (context -> status == 0 ) {
90+ redirectionio_release_connection (conn , config , r -> pool );
91+
9092 return DECLINED ;
9193 }
9294
@@ -96,6 +98,8 @@ static int redirectionio_redirect_handler(request_rec *r) {
9698
9799 r -> status = context -> status ;
98100
101+ redirectionio_release_connection (conn , config , r -> pool );
102+
99103 return context -> status ;
100104}
101105
@@ -112,14 +116,24 @@ static int redirectionio_log_handler(request_rec *r) {
112116
113117 redirectionio_context * context = ap_get_module_config (r -> request_config , & redirectionio_module );
114118
115- if (context == NULL || context -> conn == NULL ) {
119+ if (context == NULL ) {
116120 return DECLINED ;
117121 }
118122
119- if (redirectionio_protocol_log (context , r , config -> project_key ) != APR_SUCCESS ) {
123+ redirectionio_connection * conn = redirectionio_acquire_connection (config , r -> pool );
124+
125+ if (conn == NULL ) {
120126 return DECLINED ;
121127 }
122128
129+ if (redirectionio_protocol_log (conn , context , r , config -> project_key ) != APR_SUCCESS ) {
130+ redirectionio_release_connection (conn , config , r -> pool );
131+
132+ return DECLINED ;
133+ }
134+
135+ redirectionio_release_connection (conn , config , r -> pool );
136+
123137 return OK ;
124138}
125139
@@ -173,20 +187,46 @@ static apr_status_t redirectionio_create_connection(redirectionio_connection *co
173187 return rv ;
174188 }
175189
176- // rv = apr_socket_timeout_set(conn->rio_sock, 0 );
177- //
178- // if (rv != APR_SUCCESS) {
179- // ap_log_perror(APLOG_MARK, APLOG_ERR, 0, pool, "mod_redirectionio: Error setting socket timeout: %s", apr_strerror(rv, errbuf, sizeof(errbuf)));
180- //
181- // return rv;
182- // }
190+ rv = apr_socket_timeout_set (conn -> rio_sock , RIO_TIMEOUT );
191+
192+ if (rv != APR_SUCCESS ) {
193+ ap_log_perror (APLOG_MARK , APLOG_ERR , 0 , pool , "mod_redirectionio: Error setting socket timeout: %s" , apr_strerror (rv , errbuf , sizeof (errbuf )));
194+
195+ return rv ;
196+ }
183197
184198 return APR_SUCCESS ;
185199}
186200
201+ static redirectionio_connection * redirectionio_acquire_connection (redirectionio_config * config , apr_pool_t * pool ) {
202+ apr_status_t rv ;
203+ redirectionio_connection * conn ;
204+
205+ rv = apr_reslist_acquire (config -> connection_pool , (void * * )& conn );
206+
207+ if (rv != APR_SUCCESS || !conn ) {
208+ ap_log_perror (APLOG_MARK , APLOG_ERR , 0 , pool , "mod_redirectionio: Failed to acquire RIO connection from pool: %s" , apr_strerror (rv , errbuf , sizeof (errbuf )));
209+
210+ return NULL ;
211+ }
212+
213+ return conn ;
214+ }
215+
216+ static apr_status_t redirectionio_release_connection (redirectionio_connection * conn , redirectionio_config * config , apr_pool_t * pool ) {
217+ apr_status_t rv = apr_reslist_release (config -> connection_pool , conn );
218+
219+ if (rv != APR_SUCCESS ) {
220+ ap_log_perror (APLOG_MARK , APLOG_ERR , 0 , pool , "mod_redirectionio: Can not release RIO socket." );
221+ }
222+
223+ return rv ;
224+ }
225+
187226static void * create_redirectionio_dir_conf (apr_pool_t * pool , char * context ) {
227+ redirectionio_config * config = apr_pcalloc (pool , sizeof (redirectionio_config ));
228+
188229 context = context ? context : "(undefined context)" ;
189- redirectionio_config * config = apr_pcalloc (pool , sizeof (redirectionio_config ));
190230
191231 if (config ) {
192232 config -> enable = -1 ;
@@ -201,9 +241,9 @@ static void *create_redirectionio_dir_conf(apr_pool_t *pool, char *context) {
201241}
202242
203243static void * merge_redirectionio_dir_conf (apr_pool_t * pool , void * parent , void * current ) {
204- redirectionio_config * conf_parent = (redirectionio_config * ) parent ;
205- redirectionio_config * conf_current = (redirectionio_config * ) current ;
206- redirectionio_config * conf = (redirectionio_config * ) create_redirectionio_dir_conf (pool , "Merged configuration" );
244+ redirectionio_config * conf_parent = (redirectionio_config * ) parent ;
245+ redirectionio_config * conf_current = (redirectionio_config * ) current ;
246+ redirectionio_config * conf = (redirectionio_config * ) create_redirectionio_dir_conf (pool , "Merged configuration" );
207247
208248 /* Merge configurations */
209249 if (conf_current -> enable == -1 ) {
@@ -234,9 +274,80 @@ static void *merge_redirectionio_dir_conf(apr_pool_t *pool, void *parent, void *
234274 conf -> server = conf_current -> server ;
235275 }
236276
277+ if (apr_reslist_create (
278+ & conf -> connection_pool ,
279+ RIO_MIN_CONNECTIONS ,
280+ RIO_KEEP_CONNECTIONS ,
281+ RIO_MAX_CONNECTIONS ,
282+ 0 ,
283+ redirectionio_pool_construct ,
284+ redirectionio_pool_destruct ,
285+ conf ,
286+ pool
287+ ) != APR_SUCCESS ) {
288+ ap_log_perror (APLOG_MARK , APLOG_CRIT , 0 , pool , "mod_redirectionio: Failed to initialize resource pool, disabling redirectionio." );
289+
290+ conf -> enable = 0 ;
291+
292+ return conf ;
293+ }
294+
295+ apr_pool_cleanup_register (pool , conf -> connection_pool , redirectionio_child_exit , redirectionio_child_exit );
296+
237297 return conf ;
238298}
239299
300+ static apr_status_t redirectionio_pool_construct (void * * rs , void * params , apr_pool_t * pool ) {
301+ redirectionio_config * conf = (redirectionio_config * ) params ;
302+ redirectionio_connection * conn ;
303+ apr_status_t rv ;
304+
305+ if (conf -> enable != 1 ) {
306+ return APR_SUCCESS ;
307+ }
308+
309+ conn = apr_palloc (pool , sizeof (redirectionio_connection ));
310+ rv = redirectionio_create_connection (conn , conf , pool );
311+
312+ if (rv != APR_SUCCESS ) {
313+ return APR_EGENERAL ;
314+ }
315+
316+ * rs = conn ;
317+
318+ if (!* rs ) {
319+ ap_log_perror (APLOG_MARK , APLOG_CRIT , 0 , pool , "mod_redirectionio: Failed to store socket in resource list" );
320+
321+ return APR_EGENERAL ;
322+ }
323+
324+ return APR_SUCCESS ;
325+ }
326+
327+ static apr_status_t redirectionio_pool_destruct (void * resource , void * params , apr_pool_t * pool ) {
328+ if (resource ) {
329+ redirectionio_connection * conn = (redirectionio_connection * )resource ;
330+ apr_socket_close (conn -> rio_sock );
331+ }
332+
333+ return APR_SUCCESS ;
334+ }
335+
336+ static apr_status_t redirectionio_child_exit (void * resource ) {
337+ apr_reslist_t * connection_pool = (apr_reslist_t * )resource ;
338+ apr_pool_t * pool ;
339+
340+ apr_pool_create (& pool , NULL );
341+
342+ while (apr_reslist_acquired_count (connection_pool ) != 0 ) {
343+ ap_log_perror (APLOG_MARK , APLOG_ERR , 0 , pool , "mod_redirectionio: Socket pool not empty: %i" , apr_reslist_acquired_count (connection_pool ));
344+ }
345+
346+ apr_reslist_destroy (connection_pool );
347+
348+ return APR_SUCCESS ;
349+ }
350+
240351static const char * redirectionio_set_enable (cmd_parms * cmd , void * cfg , const char * arg ) {
241352 redirectionio_config * conf = (redirectionio_config * )cfg ;
242353
0 commit comments