1 #include "mod_xmltools.h"
4 /* Configuration handlers -------------------------------------------------------- */
5 static const char* mod_xmltools_set_locale_dir(cmd_parms *parms, void *config, const char *arg) {
6 mod_xmltools_config *cfg = ap_get_module_config(parms->server->module_config, &mod_xmltools);
7 cfg->locale_dir = (char*) arg;
11 static const char* mod_xmltools_set_default_locale(cmd_parms *parms, void *config, const char *arg) {
12 mod_xmltools_config *cfg = ap_get_module_config(parms->server->module_config, &mod_xmltools);
13 cfg->default_locale = (char*) arg;
17 static const char* mod_xmltools_set_pre_xsl(cmd_parms *parms, void *config, const char *arg) {
18 mod_xmltools_config *cfg = ap_get_module_config(parms->server->module_config, &mod_xmltools);
19 cfg->pre_xsl = xsltParseStylesheetFile( (xmlChar*) arg );
20 if(cfg->pre_xsl == NULL) {
21 fprintf(stderr, "Unable to parse PreXSL stylesheet %s\n", (char*) arg );
27 static const char* mod_xmltools_set_post_xsl(cmd_parms *parms, void *config, const char *arg) {
28 mod_xmltools_config *cfg = ap_get_module_config(parms->server->module_config, &mod_xmltools);
29 cfg->post_xsl = xsltParseStylesheetFile( (xmlChar*) arg );
30 if(cfg->post_xsl == NULL) {
31 fprintf(stderr, "Unable to parse PostXSL stylesheet %s\n", (char*) arg );
37 /* tell apache about our commands */
38 static const command_rec mod_xmltools_cmds[] = {
39 AP_INIT_TAKE1( CONFIG_LOCALE, mod_xmltools_set_default_locale, NULL, RSRC_CONF, "default locale"),
40 AP_INIT_TAKE1( CONFIG_LOCALE_DIR, mod_xmltools_set_locale_dir, NULL, RSRC_CONF, "locale directory"),
41 AP_INIT_TAKE1( CONFIG_PRE_XSL, mod_xmltools_set_pre_xsl, NULL, RSRC_CONF, "pre xsl"),
42 AP_INIT_TAKE1( CONFIG_POST_XSL, mod_xmltools_set_post_xsl, NULL, RSRC_CONF, "post xsl"),
46 /* build the config object */
47 static void* mod_xmltools_create_config( apr_pool_t* p, server_rec* s) {
48 mod_xmltools_config* cfg =
49 (mod_xmltools_config*) apr_palloc(p, sizeof(mod_xmltools_config));
50 cfg->default_locale = DEFAULT_LOCALE;
51 cfg->locale_dir = DEFAULT_LOCALE_DIR;
58 /* Child Init handler ----------------------------------------------------------- */
59 static void mod_xmltools_child_init(apr_pool_t *p, server_rec *s) {
63 /* Request handler -------------------------------------------------------------- */
64 static int mod_xmltools_handler (request_rec* r) {
66 /* make sure we're needed first thing*/
67 if (strcmp(r->handler, MODULE_NAME ))
70 mod_xmltools_config *cfg = ap_get_module_config(r->server->module_config, &mod_xmltools);
71 char* locale_dir = cfg->locale_dir;
72 char* default_locale = cfg->default_locale;
73 xsltStylesheetPtr pre_xsl = cfg->pre_xsl;
74 xsltStylesheetPtr post_xsl = cfg->post_xsl;
76 /* we accept get/post requests */
77 r->allowed |= (AP_METHOD_BIT << M_GET);
78 r->allowed |= (AP_METHOD_BIT << M_POST);
80 ap_set_content_type(r, "text/html; charset=utf-8");
82 string_array* params = apacheParseParms(r);
84 char* file = r->filename;
85 char* dtdfile = get_dtd_lang_file(params, default_locale, locale_dir );
90 xmlSubstituteEntitiesDefault(0);
93 if( (doc = xmlParseFile(file)) == NULL) {
94 fprintf(stderr, "\n ^-- Error parsing XML file %s\n", file);
96 return HTTP_INTERNAL_SERVER_ERROR;
104 newdoc = xsltApplyStylesheet(pre_xsl, doc, NULL );
106 fprintf(stderr, "Error applying PreXSL stylesheet\n");
115 /* process xincludes */
116 if( xmlXIncludeProcess(doc) < 0 ) {
117 fprintf(stderr, "\n ^-- Error processing XIncludes for file %s\n", file);
119 return HTTP_INTERNAL_SERVER_ERROR;
122 /* replace the DTD */
123 if(xmlReplaceDtd(doc, dtdfile) < 0) {
124 fprintf(stderr, "Error replacing DTD file with file %s\n", dtdfile);
126 return HTTP_INTERNAL_SERVER_ERROR;
130 /* force DTD entity replacement */
131 doc = xmlProcessDtdEntities(doc);
135 newdoc = xsltApplyStylesheet(post_xsl, doc, NULL );
137 fprintf(stderr, "Error applying PostXSL stylesheet\n");
145 char* xml = xmlDocToString(doc, 0);
154 xmlCleanupCharEncodingHandlers();
162 /* register callbacks */
163 static void mod_xmltools_register_hooks (apr_pool_t *p) {
164 ap_hook_handler(mod_xmltools_handler, NULL, NULL, APR_HOOK_MIDDLE);
165 ap_hook_child_init(mod_xmltools_child_init,NULL,NULL,APR_HOOK_MIDDLE);
169 /* finally, flesh the module */
170 module AP_MODULE_DECLARE_DATA mod_xmltools = {
171 STANDARD20_MODULE_STUFF,
174 mod_xmltools_create_config,
177 mod_xmltools_register_hooks,
182 /* UTILITY FUNCTIONS ----------------------------------------------------- */
183 char* get_dtd_lang_file(string_array* params, char* default_locale, char* locale_dir) {
185 /* if no locale is provided via URL, we use the default */
186 char* locale = apacheGetFirstParamValue(params, PARAM_LOCALE);
187 if(!locale) locale = default_locale;
188 if(!locale) return NULL;
190 int len = strlen(LANG_DTD) + strlen(locale) + strlen(locale_dir) + 1;
195 sprintf(dtdfile, "%s/%s/%s", locale_dir, locale, LANG_DTD );
197 return strdup(dtdfile);