@@ -58,6 +58,7 @@ typedef struct ef_filter_t {
5858typedef struct ef_dir_t {
5959 int debug ;
6060 int log_stderr ;
61+ int onfail ;
6162} ef_dir_t ;
6263
6364typedef struct ef_ctx_t {
@@ -81,7 +82,6 @@ static apr_status_t ef_input_filter(ap_filter_t *, apr_bucket_brigade *,
8182 apr_off_t );
8283
8384#define DBGLVL_SHOWOPTIONS 1
84- #define DBGLVL_ERRORCHECK 2
8585#define DBGLVL_GORY 9
8686
8787#define ERRFN_USERDATA_KEY "EXTFILTCHILDERRFN"
@@ -92,6 +92,7 @@ static void *create_ef_dir_conf(apr_pool_t *p, char *dummy)
9292
9393 dc -> debug = -1 ;
9494 dc -> log_stderr = -1 ;
95+ dc -> onfail = -1 ;
9596
9697 return dc ;
9798}
@@ -125,6 +126,13 @@ static void *merge_ef_dir_conf(apr_pool_t *p, void *basev, void *overridesv)
125126 a -> log_stderr = base -> log_stderr ;
126127 }
127128
129+ if (over -> onfail != -1 ) { /* if admin coded something... */
130+ a -> onfail = over -> onfail ;
131+ }
132+ else {
133+ a -> onfail = base -> onfail ;
134+ }
135+
128136 return a ;
129137}
130138
@@ -142,6 +150,12 @@ static const char *add_options(cmd_parms *cmd, void *in_dc,
142150 else if (!strcasecmp (arg , "NoLogStderr" )) {
143151 dc -> log_stderr = 0 ;
144152 }
153+ else if (!strcasecmp (arg , "Onfail=remove" )) {
154+ dc -> onfail = 1 ;
155+ }
156+ else if (!strcasecmp (arg , "Onfail=abort" )) {
157+ dc -> onfail = 0 ;
158+ }
145159 else {
146160 return apr_pstrcat (cmd -> temp_pool ,
147161 "Invalid ExtFilterOptions option: " ,
@@ -449,9 +463,9 @@ static apr_status_t init_ext_filter_process(ap_filter_t *f)
449463 ap_assert (rc == APR_SUCCESS );
450464 apr_pool_userdata_set (f -> r , ERRFN_USERDATA_KEY , apr_pool_cleanup_null , ctx -> p );
451465
452- if ( dc -> debug >= DBGLVL_ERRORCHECK ) {
453- rc = apr_procattr_error_check_set ( ctx -> procattr , 1 );
454- ap_assert ( rc == APR_SUCCESS ) ;
466+ rc = apr_procattr_error_check_set ( ctx -> procattr , 1 );
467+ if ( rc != APR_SUCCESS ) {
468+ return rc ;
455469 }
456470
457471 /* add standard CGI variables as well as DOCUMENT_URI, DOCUMENT_PATH_INFO,
@@ -855,7 +869,29 @@ static apr_status_t ef_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
855869
856870 if (!ctx ) {
857871 if ((rv = init_filter_instance (f )) != APR_SUCCESS ) {
858- return rv ;
872+ ctx = f -> ctx ;
873+ ap_log_rerror (APLOG_MARK , APLOG_ERR , rv , r ,
874+ "can't initialise output filter %s: %s" ,
875+ f -> frec -> name ,
876+ (ctx -> dc -> onfail == 1 ) ? "removing" : "aborting" );
877+ ap_remove_output_filter (f );
878+ if (ctx -> dc -> onfail == 1 ) {
879+ return ap_pass_brigade (f -> next , bb );
880+ }
881+ else {
882+ apr_bucket * e ;
883+ f -> r -> status_line = "500 Internal Server Error" ;
884+
885+ apr_brigade_cleanup (bb );
886+ e = ap_bucket_error_create (HTTP_INTERNAL_SERVER_ERROR ,
887+ NULL , r -> pool ,
888+ f -> c -> bucket_alloc );
889+ APR_BRIGADE_INSERT_TAIL (bb , e );
890+ e = apr_bucket_eos_create (f -> c -> bucket_alloc );
891+ APR_BRIGADE_INSERT_TAIL (bb , e );
892+ ap_pass_brigade (f -> next , bb );
893+ return AP_FILTER_ERROR ;
894+ }
859895 }
860896 ctx = f -> ctx ;
861897 }
@@ -886,7 +922,19 @@ static int ef_input_filter(ap_filter_t *f, apr_bucket_brigade *bb,
886922
887923 if (!ctx ) {
888924 if ((rv = init_filter_instance (f )) != APR_SUCCESS ) {
889- return rv ;
925+ ctx = f -> ctx ;
926+ ap_log_rerror (APLOG_MARK , APLOG_ERR , rv , f -> r ,
927+ "can't initialise input filter %s: %s" ,
928+ f -> frec -> name ,
929+ (ctx -> dc -> onfail == 1 ) ? "removing" : "aborting" );
930+ ap_remove_input_filter (f );
931+ if (ctx -> dc -> onfail == 1 ) {
932+ return ap_get_brigade (f -> next , bb , mode , block , readbytes );
933+ }
934+ else {
935+ f -> r -> status = HTTP_INTERNAL_SERVER_ERROR ;
936+ return HTTP_INTERNAL_SERVER_ERROR ;
937+ }
890938 }
891939 ctx = f -> ctx ;
892940 }
0 commit comments