Esempio n. 1
0
int xslt_transform (xmlDocPtr doc, const char *xslfilename, client_t *client)
{
    int     i, ret;
    xsl_req *x;

    thread_rwlock_rlock (&xslt_lock);
    i = xslt_cached (xslfilename, NULL, client->worker->current_time.tv_sec);
    i = xslt_req_sheet (client, doc, xslfilename, i);
    x = client->shared_data;
    switch (i)
    {
    case -1:
        thread_rwlock_unlock (&xslt_lock);
        xmlFreeDoc (doc);
        client->shared_data = NULL;
        ret = client_send_404 (client, "Could not parse XSLT file");
        break;
    case CACHESIZE:   // delayed
        thread_rwlock_unlock (&xslt_lock);
        return 0;
    default:  // found it and ok to use
        ret = xslt_send_sheet (client, doc, i);
        break;
    }
    if (x)
    {
        free (x->cache.filename);
        free (x->cache.disposition);
        free (x);
    }
    return ret;
}
Esempio n. 2
0
/* thread to read xsl file and add to the cache */
void *xslt_update (void *arg)
{
    xsl_req *x = arg;
    client_t *client = x->client;
    char *fn = x->cache.filename;
    xsltStylesheetPtr sheet;

    xmlSetStructuredErrorFunc ("xsl/file", config_xml_parse_failure);
    xsltSetGenericErrorFunc ("", log_parse_failure);

    sheet = x->cache.stylesheet = xsltParseStylesheetFile (XMLSTR(fn));
    if (sheet)
    {
        int i;

        INFO1 ("loaded stylesheet %s", x->cache.filename);
        if (sheet->mediaType && strcmp ((char*)sheet->mediaType, "text/html") != 0)
        {
            // avoid this lookup for html pages
            const char _hdr[] = "Content-Disposition: attachment; filename=\"file.";
            const size_t _hdrlen = sizeof (_hdr);
            size_t len = _hdrlen + 12;
            char *filename = malloc (len); // enough for name and extension
            strcpy (filename, _hdr);
            fserve_write_mime_ext ((char*)sheet->mediaType, filename + _hdrlen - 1, len - _hdrlen - 4);
            strcat (filename, "\"\r\n");
            x->cache.disposition = filename;
        }
        // we now have a sheet, find and update.
        thread_rwlock_wlock (&xslt_lock);
        i = xslt_cached (fn, &x->cache, time(NULL));
        xslt_send_sheet (client, x->doc, i);
    }
    else
    {
        WARN1 ("problem reading stylesheet \"%s\"", x->cache.filename);
        free (fn);
        xmlFreeDoc (x->doc);
        free (x->cache.disposition);
        client->shared_data = NULL;
        client_send_404 (client, "Could not parse XSLT file");
    }
    thread_spin_lock (&update_lock);
    xsl_updating--;
    thread_spin_unlock (&update_lock);
    free (x);
    return NULL;
}
Esempio n. 3
0
int xslt_transform (xmlDocPtr doc, const char *xslfilename, client_t *client)
{
    xmlDocPtr    res;
    xsltStylesheetPtr cur;
    int len, i;
    char **params = NULL;
    refbuf_t *content = NULL;

    client->shared_data = doc;
    thread_rwlock_rlock (&xslt_lock);
    i = xslt_cached (xslfilename, client);
    if (i < 0)
    {
        thread_rwlock_unlock (&xslt_lock);
        if (i == -2)
        {
            xmlFreeDoc (doc);
            client->shared_data = NULL;
            return client_send_404 (client, "Could not parse XSLT file");
        }
        return 0;
    }
    cur = cache[i].stylesheet;
    client->shared_data = NULL;
    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_rwlock_unlock (&xslt_lock);
        xmlFreeDoc (res);
        xmlFreeDoc (doc);
        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 (200);
        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, 200,
                "HTTP/1.0 200 OK\r\nContent-Type: %s\r\nContent-Length: %d\r\n"
                "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"
                "\r\n",
                mediatype, len);

        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);
}