?? mod-xslt.c
字號:
/*Copyright (C) 2002 Philipp Dunkel philipp@dunkel.org This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; eitherversion 2 of the License, or (at your option) any laterversion. This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details. You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/const char* g_mod_xslt_ver = "$Build: "#include "build.date"" $";#define MOD_XSLT_DEBUG#define XSLT_LOG "/usr/local/apache/logs/xslt.log"#define MOD_XSLT_VERSION "1.0.5a"#include "httpd.h"#include "http_config.h"#include "http_protocol.h"#include "ap_config.h"#include "http_log.h"#include "apr_buckets.h"#include "util_filter.h"#include "apr_strings.h"#include "apr_hash.h"#include "apr_lib.h"#include <libxml/uri.h>#include <libxslt/xslt.h>#include <libxslt/xsltInternals.h>#include <libxslt/transform.h>#include <libxslt/xsltutils.h>module AP_MODULE_DECLARE_DATA xslt_module;typedef struct { char *data; apr_size_t length;} datastore_t;static int retrievedata(request_rec *r, apr_bucket_brigade *bb, datastore_t *buffer) { char *tbuf; char *nbuf; apr_size_t tlen; apr_size_t npos; apr_bucket *b = APR_BRIGADE_FIRST(bb); apr_bucket *free_bucket; while (b!=APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(b)) { if (apr_bucket_read(b, (const char**)&tbuf, &tlen, APR_BLOCK_READ) == APR_SUCCESS) { nbuf = (char*)malloc(buffer->length + tlen); npos = 0; for(npos=0;npos < buffer->length;npos++) { nbuf[npos] = buffer->data[npos]; } for(npos=0;npos < tlen;npos++) { nbuf[buffer->length + npos] = tbuf[npos]; } buffer->length+=tlen; if (buffer->data) { free(buffer->data); } buffer->data = nbuf; } else { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "mod-xslt: Failed to read bucket!"); } free_bucket = b; b=APR_BUCKET_NEXT(b); apr_bucket_delete(free_bucket); } if (APR_BUCKET_IS_EOS(b)) { return 1; } else { return 0; }}#define IS_BLANK(val) ((((val)==32) || ((val)==8) || ((val)==10) || ((val)==13))? 1 : 0)static char *getpiparam(char *content, const char *name) { char *tempstr=strdup(content); char *cur, tmp, *start; char *retval=NULL; cur = tempstr; if (cur){ while (*cur > 0) { while(IS_BLANK(*cur)) { cur++; } if (strncmp(cur,name,strlen(name)) == 0){ cur += strlen(name); if (*cur != '=') continue; cur++; tmp = *cur; cur ++; start = cur; while ((*cur > 0) && (*cur != tmp)) cur++; if (*cur != tmp) { continue; } *cur = 0; retval = strdup(start); break; } else { while(!IS_BLANK(*cur) && (*cur > 0)) { cur++; } } cur++; } } free(tempstr); return retval;}int xsltOutputBufferWrite(void * context, const char * buffer, int len){ ap_filter_t *filter = (ap_filter_t*)context; apr_bucket_brigade *brigade = (apr_bucket_brigade *)filter->ctx; char *temp = apr_palloc(filter->r->pool,len); memcpy(temp,buffer,len); APR_BRIGADE_INSERT_TAIL(brigade, apr_bucket_transient_create(temp,len,filter->r->connection->bucket_alloc)); return len;}static xmlOutputBufferPtr xsltOutputBufferCreate(ap_filter_t *f, xmlCharEncodingHandlerPtr encoder) { xmlOutputBufferPtr ret; if (f == NULL) return(NULL); ret = xmlAllocOutputBuffer(encoder); if (ret != NULL) { ret->written = 0; ret->context = (void*)f; ret->writecallback = xsltOutputBufferWrite; ret->closecallback = NULL; /* No close callback */ } return(ret); }static void decode(char *urlstr) { char *mov = urlstr; char *tmpstr = NULL; while (*mov > 0) { if (*mov == '+') { *mov = ' '; } if (*mov == '%') { tmpstr = (char*)malloc(3 * sizeof(char)); tmpstr[0] = *(mov + 1); tmpstr[1] = *(mov + 2); tmpstr[2] = 0; *mov = (char)strtol(tmpstr,NULL,16); free(tmpstr); mov++; *mov = 0; mov += 2; strcat(urlstr,mov); mov -= 3; } mov++; }}static void addparam(char ***params,const char *key, const char* value) { int paramcnt=0; char **mover; if (*params == NULL) { *params = (char**)malloc(2 * sizeof(char**)); (*params)[0]=NULL; (*params)[1]=NULL; } if (key==NULL || value==NULL) { return; } if(strchr(key,'\'')||strchr(value,'\'')) { return; } mover = *params; while (*mover) { if(strcmp(*mover,key) == 0) { free(mover[1]); mover[1] = (char*)malloc(strlen(value) + 3); strcpy(mover[1],"'"); strcat(mover[1],value); strcat(mover[1],"'"); return; } paramcnt+=2; mover+=2; } mover = *params = (char**)realloc(*params,(paramcnt + 4) * sizeof(char**)); while (*mover) { mover++; } mover[0] = strdup(key); mover[1] = (char*)malloc(strlen(value) + 3); strcpy(mover[1],"'"); strcat(mover[1],value); strcat(mover[1],"'"); mover[2] = NULL; mover[3] = NULL;}static char **urldecode(const char* querystr) { char **params = NULL; char *query = NULL; char *mov = NULL; char *key = NULL; char *value = NULL; if (querystr == NULL) { return NULL; } query = strdup(querystr); mov = query; while (*mov > 0) { if (key == NULL) { key == mov; } if (key && !value && (*mov == '=')) { *mov = 0; value = mov + 1; } if (key && value && *mov == '&') { *mov = 0; decode(key); decode(value); addparam(¶ms,key,value); key=NULL; value=NULL; } mov++; } free(query); return params;}static void freeparams(char *** params) { char **mover = *params; if (params==NULL) { return; } if (*params == NULL) { return; } while (*mover) { free(*mover); mover++; } free(*params);}#ifdef MOD_XSLT_DEBUGstatic void show_parameters(ap_filter_t *f,char **params) { char **mover = params; while (*mover) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r, "mod-xslt: parameter(%s=%s)",*mover,*(mover+1)); mover+=2; }}#endif void xslt_error(void *ctx, const char *msg, ...) { request_rec *context = (request_rec*)ctx; char *temp = NULL; int tmplen = 0; va_list args; va_start(args,msg); tmplen = vsnprintf(temp,tmplen,msg,args); va_end(args); temp = (char*)malloc((tmplen + 1) *sizeof(char)); va_start(args,msg); tmplen = vsnprintf(temp,tmplen,msg,args); va_end; temp[tmplen] = 0; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, context, "mod-xslt: XSLT -> %s",temp); apr_table_set(context->notes, "XSLT-INVALID", "TRUE"); free(temp); return;}xsltStylesheetPtr modxsltLoadStylesheetFile(xmlDocPtr doc, xmlChar *href) { xmlURIPtr URI; xsltStylesheetPtr ret = NULL; if (href != NULL) { URI = xmlParseURI((const char *) href); if (URI == NULL) { xmlFree(href); return(NULL); } if ((URI->fragment != NULL) && (URI->scheme == NULL) && (URI->opaque == NULL) && (URI->authority == NULL) && (URI->server == NULL) && (URI->user == NULL) && (URI->path == NULL) && (URI->query == NULL)) { xmlAttrPtr ID; if (URI->fragment[0] == '#') ID = xmlGetID(doc, (const xmlChar *) &(URI->fragment[1])); else ID = xmlGetID(doc, (const xmlChar *) URI->fragment); if (ID) { xmlDocPtr fake; xmlNodePtr subtree; subtree = ID->parent; fake = xmlNewDoc(NULL); if (fake != NULL) { xmlUnlinkNode(subtree); xmlAddChild((xmlNodePtr) fake, subtree); ret = xsltParseStylesheetDoc(fake); if (ret == NULL) xmlFreeDoc(fake); } } } else { xmlChar *URL, *base; base = xmlNodeGetBase(doc, (xmlNodePtr) doc); URL = xmlBuildURI(href, base); if (URL != NULL) { ret = xsltParseStylesheetFile(URL); xmlFree(URL); } else { ret = xsltParseStylesheetFile(href); } if (base != NULL) xmlFree(base); } xmlFreeURI(URI); xmlFree(href); } return ret;}xsltStylesheetPtr modxsltLoadStylesheetPI(xmlDocPtr document, const char *useragent){ xsltStylesheetPtr ret = NULL; xmlChar *agent = NULL; xmlChar *href = NULL; xsltStylesheetPtr result = NULL; xmlNodePtr child = document->children; while ((child != NULL) && (child->type != XML_ELEMENT_NODE)) { if ((child->type == XML_PI_NODE) && (xmlStrEqual(child->name, BAD_CAST "xslt-stylesheet"))) { agent = getpiparam((char*)child->content, "agent"); href = getpiparam((char*)child->content, "href"); if (agent && href) { if (strcmp(useragent,agent)==0) { result = modxsltLoadStylesheetFile(document,href); } } if (agent) free(agent); agent = NULL; if (href) free(href); href = NULL; } child = child->next; } if (result) return result; return xsltLoadStylesheetPI(document);}#ifdef MEDIATYPEPATCHstatic void modxsltGetMediaType(xsltStylesheetPtr style) { xmlChar *prop = NULL; xmlNodePtr child = NULL; child = style->doc->children; while ((child != NULL) && (child->type != XML_ELEMENT_NODE)) { child = child->next; } child = child->children; while (child) { if ((child->type == XML_ELEMENT_NODE)&&IS_XSLT_NAME(child, "output")) { prop = xsltGetNsProp(child, (const xmlChar *) "media-type", XSLT_NAMESPACE); if (prop != NULL) { if (style->mediaType) xmlFree(style->mediaType); style->mediaType = prop; } } } }#endifstatic apr_status_t xsltparse(ap_filter_t *f,datastore_t *inbuf) { const char *conststr=NULL; xmlDocPtr document = NULL;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -