On Thu, 17 Dec 2020 17:31:20 +0000
Nick Kew <[email protected]> wrote:
> > On 17 Dec 2020, at 16:22, Joe Orton <[email protected]> wrote:
> [chop]
> Thanks for prompting me to take a proper look at where this thread
> started.
Further thought: anything hardwired will come up against future
use cases where it acts contrary to expectations and indeed
requirements. A future-proof solution is to make it configurable.
I attach a patch I've just hacked (untested): if folks are happy
with the approach I'll flesh it out and commit.
--
Nick Kew
Index: mod_xml2enc.c
===================================================================
--- mod_xml2enc.c (revision 1884632)
+++ mod_xml2enc.c (working copy)
@@ -84,12 +84,19 @@
apr_bucket_brigade* bbnext;
apr_bucket_brigade* bbsave;
const char* encoding;
+ int checkedmime;
} xml2ctx;
typedef struct {
+ int onoff;
+ const char *ctype;
+} mimetype;
+
+typedef struct {
const char* default_charset;
xmlCharEncoding default_encoding;
apr_array_header_t* skipto;
+ apr_array_header_t* mimetypes;
} xml2cfg;
typedef struct {
@@ -331,6 +338,7 @@
int pending_meta = 0;
char *ctype;
char *p;
+ xml2cfg *cfg;
if (!ctx || !f->r->content_type) {
/* log error about configuring this */
@@ -338,15 +346,38 @@
return ap_pass_brigade(f->next, bb) ;
}
- ctype = apr_pstrdup(f->r->pool, f->r->content_type);
- for (p = ctype; *p; ++p)
- if (isupper(*p))
- *p = tolower(*p);
+ if (!ctx->checkedmime) {
+ cfg = ap_get_module_config(f->r->per_dir_config, &xml2enc_module);
+ ctype = apr_pstrdup(f->r->pool, f->r->content_type);
+ for (p = ctype; *p; ++p)
+ if (isupper(*p))
+ *p = tolower(*p);
- /* only act if starts-with "text/" or contains "+xml" */
- if (strncmp(ctype, "text/", 5) && !strstr(ctype, "+xml")) {
- ap_remove_output_filter(f);
- return ap_pass_brigade(f->next, bb) ;
+ /* Check whether we're configured to act on this MIME type */
+ if (cfg->mimetypes != NULL) {
+ mimetype *conftypes = (mimetype*)cfg->mimetypes->elts;
+ int i;
+ for (i = 0; i < cfg->mimetypes->nelts; ++i) {
+ if (!strncmp(conftypes[i].ctype, ctype,
+ strlen(conftypes[i].ctype))) {
+ if (conftypes[i].onoff == 0) {
+ ap_remove_output_filter(f);
+ return ap_pass_brigade(f->next, bb) ;
+ }
+ ctx->checkedmime = 1;
+ break;
+ }
+ }
+ }
+
+ /* else only act if starts-with "text/" or contains "xml" */
+ if (!ctx->checkedmime) {
+ if (strncmp(ctype, "text/", 5) && !strstr(ctype, "xml")) {
+ ap_remove_output_filter(f);
+ return ap_pass_brigade(f->next, bb) ;
+ }
+ ctx->checkedmime = 1;
+ }
}
if (ctx->bbsave == NULL) {
@@ -637,6 +668,27 @@
attr->val = arg;
return NULL;
}
+static const char* set_mimetype(cmd_parms* cmd, void* CFG, const char* arg)
+{
+ mimetype* type;
+ xml2cfg* cfg = CFG;
+ if (cfg->mimetypes == NULL)
+ cfg->mimetypes = apr_array_make(cmd->pool, 6, sizeof(mimetype));
+ type = apr_array_push(cfg->mimetypes);
+ if (arg[0] == '-') {
+ type->onoff = 0;
+ type->ctype = arg+1;
+ }
+ else if (arg[0] == '+') {
+ type->onoff = 1;
+ type->ctype = arg+1;
+ }
+ else {
+ type->onoff = 1;
+ type->ctype = arg;
+ }
+ return NULL;
+}
static const command_rec xml2enc_cmds[] = {
AP_INIT_TAKE1("xml2EncDefault", set_default, NULL, OR_ALL,
@@ -645,6 +697,8 @@
"EncodingAlias charset alias [more aliases]"),
AP_INIT_ITERATE("xml2StartParse", set_skipto, NULL, OR_ALL,
"Ignore anything in front of the first of these elements"),
+ AP_INIT_ITERATE("xml2MimeType", set_mimetype, NULL, OR_ALL,
+ "List MIME types to process or leave untouched"),
{ NULL }
};
static void* xml2enc_config(apr_pool_t* pool, char* x)
@@ -664,6 +718,7 @@
ret->default_charset = add->default_charset
? add->default_charset : base->default_charset;
ret->skipto = add->skipto ? add->skipto : base->skipto;
+ ret->mimetypes = add->mimetypes ? add->mimetypes : base->mimetypes;
return ret;
}