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