int xslt_transform (xmlDocPtr doc, const char *xslfilename, client_t *client) { xmlDocPtr res; xsltStylesheetPtr cur; int len; refbuf_t *content = NULL; char **params = NULL; xmlSetGenericErrorFunc ("", log_parse_failure); xsltSetGenericErrorFunc ("", log_parse_failure); thread_mutex_lock(&xsltlock); cur = xslt_get_stylesheet(xslfilename); if (cur == NULL) { thread_mutex_unlock(&xsltlock); ERROR1 ("problem reading stylesheet \"%s\"", xslfilename); return client_send_404 (client, "Could not parse XSLT file"); } if (client->parser->queryvars) { // annoying but we need to surround the args with ' when passing them in int i, arg_count = client->parser->queryvars->length * 2; avl_node *node = avl_get_first (client->parser->queryvars); params = calloc (arg_count+1, sizeof (char *)); for (i = 0; node && i < arg_count; node = avl_get_next (node)) { http_var_t *param = (http_var_t *)node->key; char *tmp = util_url_escape (param->value); params[i++] = param->name; // use alloca for now, should really url esc into a supplied buffer params[i] = (char*)alloca (strlen (tmp) + 3); sprintf (params[i++], "\'%s\'", tmp); free (tmp); } params[i] = NULL; } res = xsltApplyStylesheet (cur, doc, (const char **)params); free (params); if (res == NULL || xslt_SaveResultToBuf (&content, &len, res, cur) < 0) { thread_mutex_unlock (&xsltlock); xmlFreeDoc (res); WARN1 ("problem applying stylesheet \"%s\"", xslfilename); return client_send_404 (client, "XSLT problem"); } else { /* the 100 is to allow for the hardcoded headers */ refbuf_t *refbuf = refbuf_new (100); const char *mediatype = NULL; /* lets find out the content type to use */ if (cur->mediaType) mediatype = (char *)cur->mediaType; else { /* check method for the default, a missing method assumes xml */ if (cur->method && xmlStrcmp (cur->method, XMLSTR("html")) == 0) mediatype = "text/html"; else if (cur->method && xmlStrcmp (cur->method, XMLSTR("text")) == 0) mediatype = "text/plain"; else mediatype = "text/xml"; } snprintf (refbuf->data, 100, "HTTP/1.0 200 OK\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\n", mediatype, len); thread_mutex_unlock (&xsltlock); client->respcode = 200; client_set_queue (client, NULL); client->refbuf = refbuf; refbuf->len = strlen (refbuf->data); refbuf->next = content; } xmlFreeDoc(res); return fserve_setup_client (client); }
// requires xslt_lock before being called, released on return static int xslt_send_sheet (client_t *client, xmlDocPtr doc, int idx) { xmlDocPtr res; xsltStylesheetPtr cur = cache [idx].stylesheet; char **params = NULL; refbuf_t *content = NULL; int len; if (client->parser->queryvars) { // annoying but we need to surround the args with ' when passing them in int j, arg_count = client->parser->queryvars->length * 2; avl_node *node = avl_get_first (client->parser->queryvars); params = calloc (arg_count+1, sizeof (char *)); for (j = 0; node && j < arg_count; node = avl_get_next (node)) { http_var_t *param = (http_var_t *)node->key; char *tmp = util_url_escape (param->value); params[j++] = param->name; // use alloca for now, should really url esc into a supplied buffer params[j] = (char*)alloca (strlen (tmp) + 3); sprintf (params[j++], "\'%s\'", tmp); free (tmp); } params[j] = NULL; } res = xsltApplyStylesheet (cur, doc, (const char **)params); free (params); client->shared_data = NULL; if (res == NULL || xslt_SaveResultToBuf (&content, &len, res, cur) < 0) { thread_rwlock_unlock (&xslt_lock); xmlFreeDoc (res); xmlFreeDoc (doc); WARN1 ("problem applying stylesheet \"%s\"", cache [idx].filename); return client_send_404 (client, "XSLT problem"); } else { /* the 100 is to allow for the hardcoded headers */ refbuf_t *refbuf = refbuf_new (500); const char *mediatype = NULL; /* lets find out the content type to use */ if (cur->mediaType) mediatype = (char *)cur->mediaType; else { /* check method for the default, a missing method assumes xml */ if (cur->method && xmlStrcmp (cur->method, XMLSTR("html")) == 0) mediatype = "text/html"; else if (cur->method && xmlStrcmp (cur->method, XMLSTR("text")) == 0) mediatype = "text/plain"; else mediatype = "text/xml"; } snprintf (refbuf->data, 500, "HTTP/1.0 200 OK\r\nContent-Type: %s\r\nContent-Length: %d\r\n%s" "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n" "Cache-Control: no-store, no-cache, must-revalidate\r\n" "Pragma: no-cache\r\n%s\r\n" "Access-Control-Allow-Origin: *\r\n" "Access-Control-Allow-Headers: Origin, Accept, X-Requested-With, Content-Type\r\n" "Access-Control-Allow-Methods: GET, OPTIONS, HEAD\r\n" "\r\n", mediatype, len, cache[idx].disposition ? cache[idx].disposition : "", client_keepalive_header (client)); thread_rwlock_unlock (&xslt_lock); client->respcode = 200; client_set_queue (client, NULL); client->refbuf = refbuf; refbuf->len = strlen (refbuf->data); refbuf->next = content; } xmlFreeDoc(res); xmlFreeDoc(doc); return fserve_setup_client (client); }