1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 /*
20  * ====================================================================
21  * Configuration information for httpd.conf:
22  * ====================================================================
23 	<Location /xslt>
24 			AddHandler mod_xslt .html
25 			AddHandler mod_xslt .txt
26 	</Location>
27  * ====================================================================
28 */
29 #include "httpd.h"
30 #include "http_config.h"
31 #include "http_protocol.h"
32 #include "http_log.h"
33 #include "util_script.h"
34 #include "http_main.h"
35 #include "http_request.h"
36 
37 
38 
39 #include <xalanc/XalanTransformer/XalanCAPI.h>
40 
41 
42 
xslt_init(server_rec * s,pool * p)43 static void xslt_init(server_rec *s, pool *p)
44 {
45 	ap_add_version_component("mod_xslt/Xalan/1.0");
46 }
47 
48 
49 
xslt_child_init(server_rec * s,pool * p)50 static void xslt_child_init(server_rec *s, pool *p)
51 {
52 	XalanInitialize();
53 }
54 
55 
56 
xslt_child_exit(server_rec * s,pool * p)57 static void xslt_child_exit(server_rec *s, pool *p)
58 {
59 	XalanTerminate(1);
60 }
61 
62 
63 
64 typedef struct CONTROL_STRUCT_TAG
65 {
66 	request_rec*	r;
67 	int				fHeaderSent;
68 } CONTROL_STRUCT;
69 
70 
71 
xalan_output_handler(const char * data,CallbackSizeType length,void * handle)72 static CallbackSizeType xalan_output_handler(const char *data, CallbackSizeType length, void *handle)
73 {
74 	CONTROL_STRUCT* c = (CONTROL_STRUCT*)handle;
75 
76 	if (c->fHeaderSent == 0)
77 	{
78 		c->fHeaderSent = 1;
79 
80 		ap_send_http_header(c->r);
81 	}
82 
83 	return ap_rwrite(data, length, c->r);
84 }
85 
86 
87 
xalan_flush_handler(void * handle)88 static void xalan_flush_handler(void *handle)
89 {
90 	CONTROL_STRUCT* c = (CONTROL_STRUCT*)handle;
91 
92 	ap_rflush(c->r);
93 }
94 
95 
96 
xslt_handler(request_rec * r)97 static int xslt_handler(request_rec *r)
98 {
99 	char * mimetype		= NULL;
100 	char * filename		= NULL;
101 	char * xmlfilename	= NULL;
102 	char * xslfilename	= NULL;
103 
104 	XalanHandle xalan = NULL;
105 
106 	int i;
107 	int dot_point;
108 
109 	int	error = DECLINED;
110 
111 	CONTROL_STRUCT	control_struct =
112 	{
113 		0,
114 		0
115 	};
116 
117 	control_struct.r = r;
118 
119 	mimetype = ap_pstrcat(r->pool, r->filename, NULL);
120 
121     /* Find the extension without any assumptions on string.h */
122 
123     dot_point = 0;
124 	i = 0;
125 
126     while (mimetype[i] != '\0') {
127         if (mimetype[i] == '.')
128              dot_point = i;
129         ++i;
130     }
131 
132     if (dot_point == 0) {
133 
134         fprintf(stderr, "Unable to find extension of : %s\n", mimetype);
135         r->uri = mimetype;
136 
137         return DECLINED;
138     }
139 
140     filename = ap_pstrndup(r->pool, r->filename,dot_point);
141 
142 	xmlfilename = ap_pstrcat(r->pool,filename,".xml",NULL);
143 
144 	xslfilename = ap_pstrcat(r->pool,filename,".xsl",NULL);
145 
146 	xalan = CreateXalanTransformer();
147 
148 	error = XalanTransformToHandler(xmlfilename, xslfilename, xalan, &control_struct, xalan_output_handler, xalan_flush_handler);
149 
150 	if(error)
151 	{
152 	    const char* const	msg = XalanGetLastError(xalan);
153 
154 	    fprintf(stderr,"mod_xslt: %s: %s\n", r->filename, msg);
155 
156 		r->uri = filename;
157 
158 		return DECLINED;
159 	}
160 
161 	DeleteXalanTransformer(xalan);
162 
163 	return OK;
164 }
165 
166 
167 
168 static const handler_rec xslt_handlers[] =
169 {
170     {"mod_xslt", xslt_handler},
171     {NULL, NULL}
172 };
173 
174 
175 
176 module MODULE_VAR_EXPORT xslt_module =
177 {
178     STANDARD_MODULE_STUFF,
179     xslt_init,		/* initializer */
180     NULL,			/* create per-directory config structure */
181     NULL,			/* merge per-directory config structures */
182     NULL,			/* create per-server config structure */
183     NULL,			/* merge per-server config structures */
184     NULL,			/* command table */
185     xslt_handlers,	/* handlers */
186     NULL,			/* translate_handler */
187     NULL,			/* check_user_id */
188     NULL,			/* check auth */
189     NULL,			/* check access */
190     NULL,			/* type_checker */
191     NULL,			/* pre-run fixups */
192     NULL,			/* logger */
193     NULL,			/* header parser */
194     xslt_child_init,/* child_init */
195     xslt_child_exit,/* child_exit */
196     NULL			/* post read-request */
197 };
198