mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-01 11:15:57 +00:00
completed xslt plugin
This commit is contained in:
+151
-3
@@ -26,6 +26,17 @@ struct uwsgi_xslt_config {
|
||||
uint16_t content_type_len;
|
||||
} uxslt;
|
||||
|
||||
struct uwsgi_router_xslt_conf {
|
||||
char *doc;
|
||||
uint16_t doc_len;
|
||||
char *stylesheet;
|
||||
uint16_t stylesheet_len;
|
||||
char *params;
|
||||
uint16_t params_len;
|
||||
char *content_type;
|
||||
uint16_t content_type_len;
|
||||
};
|
||||
|
||||
struct uwsgi_option uwsgi_xslt_options[] = {
|
||||
{"xslt-docroot", required_argument, 0, "add a document_root for xslt processing", uwsgi_opt_add_string_list, &uxslt.docroot, 0},
|
||||
{"xslt-ext", required_argument, 0, "search for xslt stylesheets with the specified extension", uwsgi_opt_add_string_list, &uxslt.ext, 0},
|
||||
@@ -35,7 +46,34 @@ struct uwsgi_option uwsgi_xslt_options[] = {
|
||||
{NULL, 0, 0, NULL, NULL, NULL, 0},
|
||||
};
|
||||
|
||||
static char *uwsgi_xslt_apply(char *xmlfile, char *xsltfile, char **params, int *rlen) {
|
||||
static char *uwsgi_xslt_apply(char *xmlfile, char *xsltfile, char *params, int *rlen) {
|
||||
|
||||
char **vparams = NULL;
|
||||
char *tmp_params;
|
||||
uint16_t count = 0;
|
||||
if (params) {
|
||||
// first count the number of items
|
||||
size_t i;
|
||||
size_t params_len = strlen(params);
|
||||
for(i=0;i<params_len;i++) {
|
||||
if (params[i] == '=') {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
vparams = uwsgi_calloc( sizeof(char *) * ((count * 2) + 1));
|
||||
tmp_params = uwsgi_str(params);
|
||||
char *p = strtok(tmp_params, "&");
|
||||
int pos = 0;
|
||||
while(p) {
|
||||
char *equal = strchr(p, '=');
|
||||
if (equal) {
|
||||
*equal = 0;
|
||||
vparams[pos] = p; pos++;
|
||||
vparams[pos] = uwsgi_concat3("\"", equal+1, "\""); pos++;
|
||||
}
|
||||
p = strtok(NULL, "&");
|
||||
}
|
||||
}
|
||||
|
||||
// we reset them every time to avoid collision with other xml engines
|
||||
xmlSubstituteEntitiesDefault(1);
|
||||
@@ -43,19 +81,34 @@ static char *uwsgi_xslt_apply(char *xmlfile, char *xsltfile, char **params, int
|
||||
|
||||
xmlDocPtr doc = xmlParseFile(xmlfile);
|
||||
if (!doc) {
|
||||
if (vparams) {
|
||||
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
|
||||
free(tmp_params);
|
||||
free(vparams);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xsltStylesheetPtr ss = xsltParseStylesheetFile((const xmlChar *) xsltfile);
|
||||
if (!ss) {
|
||||
xmlFreeDoc(doc);
|
||||
if (vparams) {
|
||||
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
|
||||
free(tmp_params);
|
||||
free(vparams);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xmlDocPtr res = xsltApplyStylesheet(ss, doc, (const char **) params);
|
||||
xmlDocPtr res = xsltApplyStylesheet(ss, doc, (const char **) vparams);
|
||||
if (!res) {
|
||||
xsltFreeStylesheet(ss);
|
||||
xmlFreeDoc(doc);
|
||||
if (vparams) {
|
||||
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
|
||||
free(tmp_params);
|
||||
free(vparams);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -64,6 +117,11 @@ static char *uwsgi_xslt_apply(char *xmlfile, char *xsltfile, char **params, int
|
||||
xsltFreeStylesheet(ss);
|
||||
xmlFreeDoc(res);
|
||||
xmlFreeDoc(doc);
|
||||
if (vparams) {
|
||||
int i; for(i=1;i<(count*2);i+=2) free(vparams[i]);
|
||||
free(tmp_params);
|
||||
free(vparams);
|
||||
}
|
||||
if (ret < 0) return NULL;
|
||||
return (char *) output;
|
||||
}
|
||||
@@ -78,6 +136,8 @@ static int uwsgi_request_xslt(struct wsgi_request *wsgi_req) {
|
||||
size_t filename_len = 0;
|
||||
char stylesheet[PATH_MAX+1];
|
||||
size_t stylesheet_len = 0;
|
||||
|
||||
char *params = NULL;
|
||||
|
||||
if (uwsgi_parse_vars(wsgi_req)) {
|
||||
return -1;
|
||||
@@ -215,8 +275,12 @@ static int uwsgi_request_xslt(struct wsgi_request *wsgi_req) {
|
||||
return UWSGI_OK;
|
||||
|
||||
apply:
|
||||
if (wsgi_req->query_string_len > 0) {
|
||||
params = uwsgi_concat2n(wsgi_req->query_string, wsgi_req->query_string_len, "", 0);
|
||||
}
|
||||
// we have both the file and the stylesheet, let's run the engine
|
||||
output = uwsgi_xslt_apply(filename, stylesheet, NULL, &output_rlen);
|
||||
output = uwsgi_xslt_apply(filename, stylesheet, params, &output_rlen);
|
||||
if (params) free(params);
|
||||
if (!output) {
|
||||
uwsgi_500(wsgi_req);
|
||||
return UWSGI_OK;
|
||||
@@ -249,10 +313,94 @@ static void uwsgi_xslt_log(struct wsgi_request *wsgi_req) {
|
||||
log_request(wsgi_req);
|
||||
}
|
||||
|
||||
static int uwsgi_routing_func_xslt(struct wsgi_request *wsgi_req, struct uwsgi_route *ur){
|
||||
|
||||
struct uwsgi_router_xslt_conf *urxc = (struct uwsgi_router_xslt_conf *) ur->data2;
|
||||
|
||||
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
|
||||
uint16_t *subject_len = (uint16_t *) (((char *)(wsgi_req))+ur->subject_len);
|
||||
|
||||
struct uwsgi_buffer *ub_doc = NULL;
|
||||
struct uwsgi_buffer *ub_stylesheet = NULL;
|
||||
struct uwsgi_buffer *ub_params = NULL;
|
||||
struct uwsgi_buffer *ub_content_type = NULL;
|
||||
|
||||
ub_doc = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->doc, urxc->doc_len);
|
||||
if (!ub_doc) goto end;
|
||||
ub_stylesheet = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->stylesheet, urxc->stylesheet_len);
|
||||
if (!ub_stylesheet) goto end;
|
||||
|
||||
if (urxc->params) {
|
||||
ub_params = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->params, urxc->params_len);
|
||||
if (!ub_params) goto end;
|
||||
}
|
||||
|
||||
if (urxc->content_type) {
|
||||
ub_content_type = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, urxc->content_type, urxc->content_type_len);
|
||||
if (!ub_content_type) goto end;
|
||||
}
|
||||
|
||||
int rlen;
|
||||
char *output = uwsgi_xslt_apply( ub_doc->buf, ub_stylesheet->buf, ub_params ? ub_params->buf : NULL, &rlen);
|
||||
if (!output) goto end;
|
||||
|
||||
if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) goto end;
|
||||
if (uwsgi_response_add_content_length(wsgi_req, rlen)) goto end;
|
||||
if (uwsgi_response_add_content_type(wsgi_req, urxc->content_type, urxc->content_type_len)) goto end;
|
||||
|
||||
uwsgi_response_write_body_do(wsgi_req, output, rlen);
|
||||
xmlFree(output);
|
||||
|
||||
end:
|
||||
if (ub_doc) uwsgi_buffer_destroy(ub_doc);
|
||||
if (ub_stylesheet) uwsgi_buffer_destroy(ub_stylesheet);
|
||||
if (ub_params) uwsgi_buffer_destroy(ub_params);
|
||||
if (ub_content_type) uwsgi_buffer_destroy(ub_content_type);
|
||||
return UWSGI_ROUTE_BREAK;
|
||||
}
|
||||
|
||||
|
||||
static int uwsgi_router_xslt(struct uwsgi_route *ur, char *args) {
|
||||
ur->func = uwsgi_routing_func_xslt;
|
||||
ur->data = args;
|
||||
ur->data_len = strlen(args);
|
||||
struct uwsgi_router_xslt_conf *urxc = uwsgi_calloc(sizeof(struct uwsgi_router_xslt_conf));
|
||||
if (uwsgi_kvlist_parse(ur->data, ur->data_len, ',', '=',
|
||||
"doc", &urxc->doc,
|
||||
"stylesheet", &urxc->stylesheet,
|
||||
"content_type", &urxc->content_type,
|
||||
"params", &urxc->params,
|
||||
NULL)) {
|
||||
uwsgi_log("invalid route syntax: %s\n", args);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!urxc->doc && !urxc->stylesheet) {
|
||||
uwsgi_log("invalid route syntax: you need to specify a doc and a stylesheet\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
urxc->doc_len = strlen(urxc->doc);
|
||||
urxc->stylesheet_len = strlen(urxc->stylesheet);
|
||||
|
||||
if (urxc->params) urxc->params_len = strlen(urxc->params);
|
||||
if (!urxc->content_type) urxc->content_type = "text/html";
|
||||
urxc->content_type_len = strlen(urxc->content_type);
|
||||
ur->data2 = urxc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void router_xslt_register() {
|
||||
uwsgi_register_router("xslt", uwsgi_router_xslt);
|
||||
}
|
||||
|
||||
|
||||
struct uwsgi_plugin xslt_plugin = {
|
||||
.name = "xslt",
|
||||
.modifier1 = 23,
|
||||
.options = uwsgi_xslt_options,
|
||||
.request = uwsgi_request_xslt,
|
||||
.after_request = uwsgi_xslt_log,
|
||||
.on_load = router_xslt_register,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- Edited by XMLSpy® -->
|
||||
<catalog>
|
||||
<cd>
|
||||
<title>Quintessence</title>
|
||||
<artist>Borknagar</artist>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Torn Beyond Reason</title>
|
||||
<artist>Woods Of Desolation</artist>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Autumn Aurora</title>
|
||||
<artist>Drudkh</artist>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Om</title>
|
||||
<artist>Negura Bunget</artist>
|
||||
</cd>
|
||||
<cd>
|
||||
<title>Frostnacht</title>
|
||||
<artist>Helrunar</artist>
|
||||
</cd>
|
||||
</catalog>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0"?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<body>
|
||||
<h2>Blackmetal albums</h2>
|
||||
<table border="1">
|
||||
<tr bgcolor="black">
|
||||
<th style="color:white">Title</th>
|
||||
<th style="color:white">Artist</th>
|
||||
</tr>
|
||||
<xsl:for-each select="catalog/cd">
|
||||
<tr>
|
||||
<td><xsl:value-of select="title"/></td>
|
||||
<td><xsl:value-of select="artist"/></td>
|
||||
<td>-<xsl:value-of select="$foobar"/>-</td>
|
||||
<td><xsl:value-of select="$agent"/></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
@@ -0,0 +1,5 @@
|
||||
[uwsgi]
|
||||
http-socket = :9090
|
||||
plugin = xslt
|
||||
xml_storage = t/xslt
|
||||
route = /(.*)$ xslt:doc=%(xml_storage)/$1.xml,stylesheet=%(xml_storage)/$1.xml.xslt,content_type=text/html,params=foobar=test&agent=${HTTP_USER_AGENT}
|
||||
Reference in New Issue
Block a user