Esempio n. 1
0
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);
}
Esempio n. 2
0
// 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);
}