char *language_type; /* Added with AddLanguage... */
char *handler; /* Added with AddHandler... */
char *charset_type; /* Added with AddCharset... */
+ int copy; /* To avoid dupping in the merge */
} extension_info;
typedef struct {
apr_hash_t *extension_mappings; /* Map from extension name to
* extension_info structure */
+ int copy_mappings; /* To avoid dupping in the merge */
+
apr_array_header_t *handlers_remove; /* List of handlers to remove */
apr_array_header_t *types_remove; /* List of MIME types to remove */
apr_array_header_t *encodings_remove; /* List of encodings to remove */
(mime_dir_config *) apr_palloc(p, sizeof(mime_dir_config));
new->extension_mappings = apr_hash_make(p);
+ new->copy_mappings = 0;
+
new->handlers_remove = NULL;
new->types_remove = NULL;
new->encodings_remove = NULL;
extension_info *overlay_info, *base_info;
apr_hash_this(index, (const void**)&key, &klen, (void**)&overlay_info);
+
base_info = (extension_info*)apr_hash_get(base, key, klen);
+
if (base_info) {
+ if (!base_info->copy) {
+ extension_info *copyinfo = base_info;
+ base_info = (extension_info*)apr_palloc(p, sizeof(*base_info));
+ apr_hash_set(base, key, klen, base_info);
+ memcpy(base_info, copyinfo, sizeof(*base_info));
+ base_info->copy = 1;
+ }
+
if (overlay_info->forced_type) {
base_info->forced_type = overlay_info->forced_type;
}
}
}
else {
- base_info = (extension_info*)apr_palloc(p, sizeof(extension_info));
- memcpy(base_info, overlay_info, sizeof(extension_info));
- apr_hash_set(base, key, klen, base_info);
+ apr_hash_set(base, key, klen, overlay_info);
}
}
}
int i;
attrib_info *suffix;
- if (base->extension_mappings == NULL) {
- new->extension_mappings = add->extension_mappings;
- }
- else if (add->extension_mappings == NULL) {
- new->extension_mappings = base->extension_mappings;
- }
- else {
- new->extension_mappings = apr_hash_make(p);
- overlay_extension_mappings(p, base->extension_mappings,
- new->extension_mappings);
+ if (base->extension_mappings && add->extension_mappings) {
+ if (base->copy_mappings)
+ new->extension_mappings = base->extension_mappings;
+ else {
+ new->extension_mappings = apr_hash_make(p);
+ /* XXX as slow as can be... just use an apr_hash_dup! */
+ overlay_extension_mappings(p, base->extension_mappings,
+ new->extension_mappings);
+ }
overlay_extension_mappings(p, add->extension_mappings,
new->extension_mappings);
+ new->copy_mappings = 1;
+ }
+ else {
+ if (base->extension_mappings == NULL) {
+ new->extension_mappings = add->extension_mappings;
+ new->copy_mappings = add->copy_mappings;
+ }
+ else if (add->extension_mappings == NULL) {
+ new->extension_mappings = base->extension_mappings;
+ new->copy_mappings = base->copy_mappings;
+ }
+ if (!new->copy_mappings && (add->handlers_remove
+ || add->types_remove
+ || add->encodings_remove)) {
+ apr_hash_t *copyhash = new->extension_mappings;
+ new->extension_mappings = apr_hash_make(p);
+ /* XXX as slow as can be... just use an apr_hash_dup! */
+ overlay_extension_mappings(p, copyhash, new->extension_mappings);
+ new->copy_mappings = 1;
+ }
}
if (add->handlers_remove) {
suffix[i].name,
APR_HASH_KEY_STRING);
if (exinfo) {
+ if (!exinfo->copy) {
+ extension_info *copyinfo = exinfo;
+ exinfo = (extension_info*)apr_palloc(p, sizeof(*exinfo));
+ apr_hash_set(new->extension_mappings, suffix[i].name,
+ APR_HASH_KEY_STRING, exinfo);
+ memcpy(exinfo, copyinfo, sizeof(*exinfo));
+ exinfo->copy = 1;
+ }
exinfo->handler = NULL;
}
}
suffix[i].name,
APR_HASH_KEY_STRING);
if (exinfo) {
+ if (!exinfo->copy) {
+ extension_info *copyinfo = exinfo;
+ exinfo = (extension_info*)apr_palloc(p, sizeof(*exinfo));
+ apr_hash_set(new->extension_mappings, suffix[i].name,
+ APR_HASH_KEY_STRING, exinfo);
+ memcpy(exinfo, copyinfo, sizeof(*exinfo));
+ exinfo->copy = 1;
+ }
exinfo->forced_type = NULL;
}
}
suffix[i].name,
APR_HASH_KEY_STRING);
if (exinfo) {
+ if (!exinfo->copy) {
+ extension_info *copyinfo = exinfo;
+ exinfo = (extension_info*)apr_palloc(p, sizeof(*exinfo));
+ apr_hash_set(new->extension_mappings, suffix[i].name,
+ APR_HASH_KEY_STRING, exinfo);
+ memcpy(exinfo, copyinfo, sizeof(*exinfo));
+ exinfo->copy = 1;
+ }
exinfo->encoding_type = NULL;
}
}
return new;
}
+
static extension_info *get_extension_info(apr_pool_t *p, mime_dir_config *m,
const char* key)
{
exinfo = (extension_info*)apr_hash_get(m->extension_mappings, key,
APR_HASH_KEY_STRING);
if (!exinfo) {
+ /* pcalloc sets ->copy to false */
exinfo = apr_pcalloc(p, sizeof(extension_info));
apr_hash_set(m->extension_mappings, apr_pstrdup(p, key),
APR_HASH_KEY_STRING, exinfo);
types_confname = ap_server_root_relative(p, types_confname);
- if ((status = ap_pcfg_openfile(&f, p, types_confname)) != APR_SUCCESS) {
+ if ((status = ap_pcfg_openfile(&f, ptemp, types_confname)) != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, status, s,
"could not open mime types config file %s.", types_confname);
exit(1);