00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ngx_http_xslt2_xml.h"
00023 #include "ngx_http_xslt2_filter_module.h"
00024
00025
00026
00027 static ngx_http_xslt2_sheet_t *
00028 ngx_http_xslt2_xml_create_new_stylesheet(ngx_http_xslt2_xml_data_t *xml_data);
00029 static ngx_int_t
00030 ngx_http_xslt2_xml_return_original(ngx_http_xslt2_xml_data_t *xml_data);
00031 static ngx_int_t
00032 ngx_http_xslt2_xml_get_local_stylesheet(ngx_http_xslt2_sheet_t *sheet);
00033 static ngx_int_t
00034 ngx_http_xslt2_xml_get_external_stylesheet(ngx_http_xslt2_sheet_t *sheet);
00035 static void
00036 ngx_http_xslt2_xml_download_handler(ngx_http_download_conn_t *dl_ctx);
00037 static ngx_int_t
00038 ngx_http_xslt2_xml_parse_stylesheet(ngx_http_xslt2_sheet_t *sheet);
00039 static ngx_int_t
00040 ngx_http_xslt2_xml_apply_stylesheets(ngx_http_xslt2_xml_data_t *xml_data);
00041 static ngx_int_t
00042 ngx_http_xslt2_xml_get_cached_stylesheet(ngx_http_request_t *r, ngx_http_xslt2_sheet_t *sheet);
00043 static void
00044 ngx_http_xslt2_xml_mxcache_get_handler(ngx_http_mxcache_conn_t *conn);
00045 static ngx_int_t
00046 ngx_http_xslt2_xml_set_cached_stylesheet(ngx_http_request_t *r, ngx_http_xslt2_sheet_t *sheet);
00047 static void
00048 ngx_http_xslt2_xml_mxcache_set_handler(ngx_http_mxcache_conn_t *conn);
00049 static void
00050 ngx_http_xslt2_xml_get_stylesheet(ngx_http_xslt2_sheet_t *sheet, ngx_flag_t use_cache);
00051 static void
00052 ngx_http_xslt2_xml_stylesheet_node(ngx_http_xslt2_xml_data_t *xml_data, const xmlChar *pidata);
00053 static void
00054 ngx_http_xslt2_xml_stylesheet_error(ngx_http_xslt2_xml_data_t *xml_data, char *msg, ...);
00055
00056
00057 static void ngx_http_xslt2_xml_sax_start_document(void *data);
00058 static void ngx_http_xslt2_xml_sax_end_document(void *data);
00059 static void ngx_http_xslt2_xml_sax_internal_subset(void *data, const xmlChar *name,
00060 const xmlChar *externalId, const xmlChar *systemId);
00061 static void ngx_http_xslt2_xml_sax_external_subset(void *data, const xmlChar *name,
00062 const xmlChar *externalId, const xmlChar *systemId);
00063 static void ngx_http_xslt2_xml_sax_entity_decl(void *data, const xmlChar *name,
00064 int type, const xmlChar *publicId, const xmlChar *systemId,
00065 xmlChar *content);
00066 static void ngx_http_xslt2_xml_sax_attribute_decl(void *data, const xmlChar *elem,
00067 const xmlChar *fullname, int type, int def, const xmlChar *defaultValue,
00068 xmlEnumerationPtr tree);
00069 static void ngx_http_xslt2_xml_sax_element_decl(void *data, const xmlChar * name,
00070 int type, xmlElementContentPtr content);
00071 static void ngx_http_xslt2_xml_sax_notation_decl(void *data, const xmlChar *name,
00072 const xmlChar *publicId, const xmlChar *systemId);
00073 static void ngx_http_xslt2_xml_sax_unparsed_entity_decl(void *data,
00074 const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId,
00075 const xmlChar *notationName);
00076 static void ngx_http_xslt2_xml_sax_start_element(void *data,
00077 const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI,
00078 int nb_namespaces, const xmlChar **namespaces, int nb_attributes,
00079 int nb_defaulted, const xmlChar **attributes);
00080 static void ngx_http_xslt2_xml_sax_end_element(void *data,
00081 const xmlChar * localname ATTRIBUTE_UNUSED,
00082 const xmlChar * prefix ATTRIBUTE_UNUSED,
00083 const xmlChar * URI ATTRIBUTE_UNUSED);
00084 static void ngx_http_xslt2_xml_sax_characters(void *data, const xmlChar *p, int len);
00085 static void ngx_http_xslt2_xml_sax_cdata_block(void *data, const xmlChar *p,
00086 int len);
00087 static xmlEntityPtr ngx_http_xslt2_xml_sax_get_entity(void *data,
00088 const xmlChar *name);
00089 static xmlEntityPtr ngx_http_xslt2_xml_sax_get_parameter_entity(void *data,
00090 const xmlChar *name);
00091 static xmlParserInputPtr ngx_http_xslt2_xml_sax_resolve_entity(void *data,
00092 const xmlChar *publicId, const xmlChar *systemId);
00093 static void ngx_http_xslt2_xml_sax_reference(void *data, const xmlChar *name);
00094 static void ngx_http_xslt2_xml_sax_comment(void *data, const xmlChar *value);
00095 static void ngx_http_xslt2_xml_sax_processing_instruction(void *data,
00096 const xmlChar *target, const xmlChar *pidata);
00097 static int ngx_http_xslt2_xml_sax_is_standalone(void *data);
00098 static int ngx_http_xslt2_xml_sax_has_internal_subset(void *data);
00099 static int ngx_http_xslt2_xml_sax_has_external_subset(void *data);
00100 static void ngx_cdecl ngx_http_xslt2_xml_sax_error(void *data, const char *msg, ...);
00101
00102
00103
00109 ngx_http_xslt2_xml_data_t* ngx_http_xslt2_xml_create_new(ngx_http_request_t *r)
00110 {
00111 ngx_http_xslt2_xml_data_t *xml_data;
00112 xmlSAXHandler *sax;
00113
00114 xml_data = ngx_pcalloc(r->pool, sizeof(ngx_http_xslt2_xml_data_t));
00115
00116 xml_data->ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
00117 if(xml_data->ctxt == NULL)
00118 {
00119 return NULL;
00120 }
00121
00122 xml_data->sax = ngx_palloc(r->pool, sizeof(xmlSAXHandler));
00123 if (xml_data->sax == NULL) {
00124 return NULL;
00125 }
00126
00127 sax = xml_data->ctxt->sax;
00128
00129 ngx_memcpy(xml_data->sax, sax, sizeof(xmlSAXHandler));
00130
00131 sax->startDocument = ngx_http_xslt2_xml_sax_start_document;
00132 sax->endDocument = ngx_http_xslt2_xml_sax_end_document;
00133
00134 sax->internalSubset = ngx_http_xslt2_xml_sax_internal_subset;
00135 sax->externalSubset = ngx_http_xslt2_xml_sax_external_subset;
00136 sax->entityDecl = ngx_http_xslt2_xml_sax_entity_decl;
00137 sax->attributeDecl = ngx_http_xslt2_xml_sax_attribute_decl;
00138 sax->elementDecl = ngx_http_xslt2_xml_sax_element_decl;
00139 sax->notationDecl = ngx_http_xslt2_xml_sax_notation_decl;
00140 sax->unparsedEntityDecl = ngx_http_xslt2_xml_sax_unparsed_entity_decl;
00141 sax->setDocumentLocator = NULL;
00142
00143 sax->startElementNs = ngx_http_xslt2_xml_sax_start_element;
00144 sax->endElementNs = ngx_http_xslt2_xml_sax_end_element;
00145
00146 sax->characters = ngx_http_xslt2_xml_sax_characters;
00147 sax->ignorableWhitespace = ngx_http_xslt2_xml_sax_characters;
00148 sax->cdataBlock = ngx_http_xslt2_xml_sax_cdata_block;
00149 sax->getEntity = ngx_http_xslt2_xml_sax_get_entity;
00150 sax->resolveEntity = ngx_http_xslt2_xml_sax_resolve_entity;
00151 sax->getParameterEntity = ngx_http_xslt2_xml_sax_get_parameter_entity;
00152 sax->reference = ngx_http_xslt2_xml_sax_reference;
00153 sax->comment = ngx_http_xslt2_xml_sax_comment;
00154 sax->processingInstruction = ngx_http_xslt2_xml_sax_processing_instruction;
00155
00156 sax->isStandalone = ngx_http_xslt2_xml_sax_is_standalone;
00157 sax->hasInternalSubset = ngx_http_xslt2_xml_sax_has_internal_subset;
00158 sax->hasExternalSubset = ngx_http_xslt2_xml_sax_has_external_subset;
00159
00160 sax->warning = NULL;
00161 sax->error = ngx_http_xslt2_xml_sax_error;
00162 sax->fatalError = ngx_http_xslt2_xml_sax_error;
00163
00164 xml_data->ctxt->userData = xml_data;
00165
00166 xml_data->ctxt->replaceEntities = 1;
00167 xml_data->ctxt->loadsubset = 1;
00168
00169
00170 xml_data->r = r;
00171
00172 return xml_data;
00173 }
00174
00183 ngx_int_t
00184 ngx_http_xslt2_xml_add_data_chunk(ngx_http_xslt2_xml_data_t *xml_data, ngx_chain_t *in)
00185 {
00186 int rc;
00187 ngx_buf_t *buf;
00188 xmlParserCtxtPtr ctxt;
00189 ngx_http_request_t *r;
00190
00191 if(xml_data == NULL || in == NULL)
00192 {
00193 return NGX_ERROR;
00194 }
00195
00196 buf = in->buf;
00197 ctxt = xml_data->ctxt;
00198 r = xml_data->r;
00199
00200 while(in != NULL)
00201 {
00202 buf = in->buf;
00203
00204 rc = xmlParseChunk(ctxt, (char *) buf->pos, (int) (buf->last - buf->pos), buf->last_buf);
00205
00206
00207 buf->pos = buf->last;
00208
00209 if(rc != 0)
00210 {
00211 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00212 "[xml_add_data_chunk] xmlParseChunk() failed, error:%d", rc);
00213 return ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00214 "<b>Error during XML parsing</b> :: %s", xml_data->libxml_error);
00215 }
00216
00217 if(xml_data->stylesheet_err != 0)
00218 {
00219 return ngx_http_xslt2_finalize_with_error(r, xml_data->stylesheet_err,
00220 (char *) xml_data->stylesheet_err_msg);
00221 }
00222
00223 in = in->next;
00224 }
00225
00226 if(buf->last_buf || buf->last_buf)
00227 {
00228 xml_data->doc = ctxt->myDoc;
00229
00230 if(xml_data->doc == NULL)
00231 {
00232 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00233 "[xml_add_data_chunk] xmlParseChunk() finalization failed");
00234 return ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00235 "<b>Error during XML parsing</b> :: %s", xml_data->libxml_error);
00236 }
00237 if(!ctxt->wellFormed)
00238 {
00239 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00240 "[xml_add_data_chunk] XML is not well formed");
00241 return ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00242 "<b>XML is not well formed</b> :: libxml error: %s", xml_data->libxml_error);
00243 }
00244 xml_data->xml_ready = 1;
00245
00246
00247 if(xml_data->sheets == NULL)
00248 {
00249 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00250 "[xml_add_data_chunk] No style sheets declared");
00251
00252 return ngx_http_xslt2_xml_return_original(xml_data);
00253 }
00254
00255 return ngx_http_xslt2_xml_apply_stylesheets(xml_data);
00256 }
00257 return NGX_OK;
00258 }
00259
00269 static ngx_int_t
00270 ngx_http_xslt2_xml_return_original(ngx_http_xslt2_xml_data_t *xml_data)
00271 {
00272 xmlChar *buf;
00273 int len;
00274
00275 ngx_http_request_t *r;
00276 ngx_chain_t *cl;
00277
00278 r = xml_data->r;
00279
00280 xmlDocDumpMemory(xml_data->doc, &buf, &len);
00281
00282 if(buf == NULL)
00283 {
00284 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00285 "[ngx_http_xslt2_xml_return_original] xsltSaveResultToString failed");
00286 return ngx_http_xslt2_finalize_with_error(r,
00287 NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
00288 }
00289
00290 cl = ngx_pcalloc(xml_data->r->pool, sizeof(ngx_chain_t));
00291 if(cl == NULL)
00292 {
00293 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00294 "[ngx_http_xslt2_xml_return_original] XML buffer chain allocation failed");
00295 return ngx_http_xslt2_finalize_with_error(r,
00296 NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
00297 }
00298
00299 cl->buf = ngx_pcalloc(xml_data->r->pool, sizeof(ngx_buf_t));
00300 if(cl->buf == NULL)
00301 {
00302 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00303 "[ngx_http_xslt2_xml_return_original] XML buffer allocation failed");
00304 return ngx_http_xslt2_finalize_with_error(r,
00305 NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
00306 }
00307
00308 cl->buf->pos = ngx_pcalloc(xml_data->r->pool, sizeof(u_char)*(len + 1));
00309 if(cl->buf->pos == NULL)
00310 {
00311 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00312 "[ngx_http_xslt2_xml_return_original] XML buffer content allocation failed");
00313 return ngx_http_xslt2_finalize_with_error(r,
00314 NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
00315 }
00316
00317 ngx_cpystrn(cl->buf->pos, (u_char *) buf, len+1);
00318
00319 cl->buf->last = cl->buf->pos + len;
00320 cl->buf->memory = 1;
00321
00322 xml_data->buffer_chain = cl;
00323 xml_data->res_len = len;
00324
00325 xmlFree(buf);
00326
00327 xml_data->done = 1;
00328
00329 return ngx_http_xslt2_process_data(r);
00330 }
00331
00332
00337 void
00338 ngx_http_xslt2_xml_cleanup(ngx_http_xslt2_xml_data_t *xml_data)
00339 {
00340 if(xml_data->doc != NULL)
00341 {
00342 xmlFreeDoc(xml_data->doc);
00343 xml_data->doc = NULL;
00344 }
00345 if(xml_data->ctxt != NULL)
00346 {
00347 xmlFreeParserCtxt(xml_data->ctxt);
00348 xml_data->ctxt = NULL;
00349 }
00350
00351
00352 while(xml_data->sheets)
00353 {
00354 if(xml_data->sheets->stylesheet != NULL)
00355 {
00356 xsltFreeStylesheet(xml_data->sheets->stylesheet);
00357 xml_data->sheets->stylesheet = NULL;
00358 }
00359
00360
00361 if(xml_data->sheets->download != NULL)
00362 {
00363 ngx_http_download_cleanup(xml_data->sheets->download);
00364 }
00365
00366 if(xml_data->sheets->xcache_get != NULL)
00367 {
00368 ngx_http_mxcache_cleanup(xml_data->sheets->xcache_get);
00369 }
00370
00371 xml_data->sheets = xml_data->sheets->next;
00372 }
00373 }
00374
00382 static ngx_http_xslt2_sheet_t *
00383 ngx_http_xslt2_xml_create_new_stylesheet(ngx_http_xslt2_xml_data_t *xml_data)
00384 {
00385 ngx_http_xslt2_sheet_t *sheet;
00386 ngx_http_request_t *r;
00387
00388 r = xml_data->r;
00389
00390 sheet = ngx_pcalloc(r->pool, sizeof(ngx_http_xslt2_sheet_t));
00391 if(sheet == NULL) {
00392 return NULL;
00393 }
00394
00395 sheet->parent_xml = xml_data;
00396 sheet->id = xml_data->sheets_n++;
00397
00398
00399 if (xml_data->sheets == NULL) {
00400 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00401 "[xml_create_new_stylesheet] new style sheet list created");
00402
00403 xml_data->sheets = xml_data->sheets_tail = sheet;
00404 xml_data->act_sheet = xml_data->sheets;
00405 }
00406
00407 else {
00408 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00409 "[xml_create_new_stylesheet] new style sheet added to list");
00410 xml_data->sheets_tail->next = sheet;
00411 xml_data->sheets_tail = sheet;
00412 }
00413
00414 return sheet;
00415 }
00416
00424 static ngx_int_t
00425 ngx_http_xslt2_xml_get_cached_stylesheet(ngx_http_request_t *r, ngx_http_xslt2_sheet_t *sheet)
00426 {
00427 ngx_http_mxcache_conn_t *xc_ctx;
00428 u_char *key;
00429 u_char *uri;
00430 ngx_int_t rc;
00431
00432 uri = sheet->res_uri;
00433
00434 if( !ngx_http_mxcache_is_enabled(r) ) {
00435 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00436 "[xml_get_cached_stylesheet] XCache disabled");
00437 return NGX_DONE;
00438 }
00439
00440 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00441 "[xml_get_cached_stylesheet] XCache get %s request", uri);
00442
00443 xc_ctx = ngx_http_mxcache_create_new(r);
00444
00445 sheet->xcache_get = xc_ctx;
00446
00447
00448 if( ngx_strncmp(uri, "http://", 7) == 0 ) {
00449 key = uri;
00450 }
00451 else {
00452 key = ngx_palloc(r->pool, r->uri.len + ngx_strlen(uri) + 1);
00453 ngx_cpystrn(key, r->uri.data, r->uri.len + 1);
00454 strcat((char*)key, (char*)uri);
00455 }
00456
00457 xc_ctx->key = key;
00458 xc_ctx->data = sheet;
00459 xc_ctx->res_uri = uri;
00460 xc_ctx->rpool = r->pool;
00461 xc_ctx->done_handler = ngx_http_xslt2_xml_mxcache_get_handler;
00462
00463
00464 rc = ngx_http_mxcache_get(xc_ctx);
00465
00466 if(rc == NGX_OK)
00467 {
00468 sheet->parent_xml->dl_in_progress++;
00469 }
00470 return rc;
00471 }
00472
00480 static void
00481 ngx_http_xslt2_xml_mxcache_get_handler(ngx_http_mxcache_conn_t *conn)
00482 {
00483 ngx_http_xslt2_sheet_t *sheet;
00484 ngx_http_xslt2_xml_data_t *xml_data;
00485 ngx_http_request_t *r;
00486 ngx_int_t rc;
00487 u_char *uri;
00488
00489
00490 sheet = conn->data;
00491 uri = conn->res_uri;
00492 xml_data = sheet->parent_xml;
00493 r = xml_data->r;
00494
00495 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, conn->log, 0,
00496 "[xml_mxcache_get_handler] XCached get %s, rc: %d", conn->res_uri, conn->error);
00497
00498 xml_data->dl_in_progress--;
00499
00500 if( conn->error == NGX_OK && conn->out_bufs && conn->data_begin ) {
00501
00502 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00503 "[xml_mxcache_get_handler] XCache get %s, OK!", conn->res_uri);
00504
00505 sheet->ready = 1;
00506
00507 sheet->buffer_chain = conn->out_bufs;
00508
00509 rc = ngx_http_xslt2_xml_parse_stylesheet(sheet);
00510 if(rc != NGX_OK)
00511 {
00512 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00513 "[xml_mxcache_get_handler] Parse style sheet error");
00514 ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00515 "<b>Error during style sheet parsing</b> :: %s", sheet->res_uri);
00516 return;
00517 }
00518
00519 ngx_http_xslt2_xml_apply_stylesheets(sheet->parent_xml);
00520 }
00521 else {
00522 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, conn->log, 0,
00523 "[xml_mxcache_get_handler] XCached get %s failed (rc: %d), trying classic method", conn->res_uri, conn->error);
00524 ngx_http_xslt2_xml_get_stylesheet(sheet, XXSLT_NO_CACHE);
00525 }
00526 }
00527
00535 static ngx_int_t
00536 ngx_http_xslt2_xml_set_cached_stylesheet(ngx_http_request_t *r, ngx_http_xslt2_sheet_t *sheet)
00537 {
00538 ngx_http_mxcache_conn_t *xc_ctx;
00539 ngx_int_t bytes;
00540 ngx_int_t size;
00541 ngx_int_t rc;
00542 u_char *key;
00543
00544 ngx_chain_t *cl;
00545 u_char *uri;
00546
00547 if( !ngx_http_mxcache_is_enabled(r) ) {
00548 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00549 "[xml_set_cached_stylesheet] mxcache disabled");
00550 return NGX_DONE;
00551 }
00552
00553 cl = sheet->buffer_chain;
00554 uri = sheet->res_uri;
00555
00556 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00557 "[xml_set_cached_stylesheet] mxcache set %s request", uri);
00558
00559 xc_ctx = ngx_http_mxcache_create_new(r);
00560
00561
00562 if( ngx_strncmp(uri, "http://", 7) == 0 ) {
00563 key = uri;
00564 }
00565 else {
00566 key = ngx_palloc(r->pool, r->uri.len + ngx_strlen(uri) + 1);
00567 ngx_cpystrn(key, r->uri.data, r->uri.len + 1);
00568 strcat((char*)key, (char*)uri);
00569 }
00570
00571
00572 xc_ctx->key = key;
00573 xc_ctx->res_uri = uri;
00574
00575 bytes = 0;
00576
00577 while( cl ) {
00578 bytes += ngx_buf_size(cl->buf);
00579
00580 if( xc_ctx->out_bufs == NULL ) {
00581 xc_ctx->out_bufs = xc_ctx->out_bufs_tail = ngx_alloc_chain_link(xc_ctx->pool);
00582 }
00583 else {
00584 xc_ctx->out_bufs_tail->next = ngx_alloc_chain_link(xc_ctx->pool);
00585 xc_ctx->out_bufs_tail = xc_ctx->out_bufs_tail->next;
00586 }
00587 size = cl->buf->last - cl->buf->pos;
00588 xc_ctx->out_bufs_tail->buf = ngx_create_temp_buf(xc_ctx->pool, size);
00589 ngx_memcpy(xc_ctx->out_bufs_tail->buf->pos, cl->buf->pos, size);
00590 xc_ctx->out_bufs_tail->buf->last = xc_ctx->out_bufs_tail->buf->pos + size;
00591
00592 cl = cl->next;
00593 }
00594 xc_ctx->out_bufs_tail->next = NULL;
00595
00596 xc_ctx->bytes = bytes;
00597
00598 xc_ctx->done_handler = ngx_http_xslt2_xml_mxcache_set_handler;
00599
00600 rc = ngx_http_mxcache_set(xc_ctx);
00601
00602 if( rc != NGX_OK ) {
00603
00604 ngx_http_mxcache_cleanup(xc_ctx);
00605 }
00606 return rc;
00607 }
00608
00615 static void
00616 ngx_http_xslt2_xml_mxcache_set_handler(ngx_http_mxcache_conn_t *conn)
00617 {
00618 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, conn->log, 0,
00619 "[xml_mxcache_set_handler] mxcached set %s, rc: %d", conn->res_uri, conn->error);
00620
00621 ngx_http_mxcache_cleanup(conn);
00622 }
00623
00632 static void
00633 ngx_http_xslt2_xml_get_stylesheet(ngx_http_xslt2_sheet_t *sheet, ngx_flag_t use_cache)
00634 {
00635 ngx_http_xslt2_xml_data_t *xml_data;
00636 ngx_http_request_t *r;
00637 ngx_int_t rc;
00638
00639 xml_data = sheet->parent_xml;
00640 r = xml_data->r;
00641
00642 if(use_cache == XXSLT_USE_CACHE)
00643 {
00644 rc = ngx_http_xslt2_xml_get_cached_stylesheet(r, sheet);
00645 }
00646 else
00647 {
00648 rc = NGX_ERROR;
00649 }
00650
00651 if(rc == NGX_OK)
00652 return;
00653
00654
00655
00656 if(xmlStrncmp(sheet->res_uri, (xmlChar *) "http://", 7) == 0)
00657 {
00658 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00659 "[xml_get_stylesheet] style sheet URL: %s", sheet->res_uri);
00660
00661 ngx_http_xslt2_xml_get_external_stylesheet(sheet);
00662 }
00663 else
00664 {
00665 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00666 "[xml_get_stylesheet] style sheet URI: %s", sheet->res_uri);
00667
00668 ngx_http_xslt2_xml_get_local_stylesheet(sheet);
00669 }
00670 }
00671
00679 static ngx_int_t
00680 ngx_http_xslt2_xml_get_local_stylesheet(ngx_http_xslt2_sheet_t *sheet)
00681 {
00682 ngx_int_t rc;
00683 ngx_http_request_t *r;
00684 ngx_str_t *uri_str;
00685 ngx_chain_t *buffer_chain = NULL;
00686 u_char *uri;
00687
00688 r = sheet->parent_xml->r;
00689 sheet->ready = 1;
00690 uri = sheet->res_uri;
00691
00692 uri_str = ngx_pcalloc(r->pool, sizeof(ngx_str_t));
00693
00694 if(uri_str == NULL)
00695 {
00696 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00697 "[xml_get_local_stylesheet] alloc failed");
00698 return ngx_http_xslt2_finalize_with_error(r,
00699 NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
00700 }
00701
00702 uri_str->data = uri;
00703 uri_str->len = ngx_strlen(uri);
00704
00705
00706 rc = ngx_http_filesync_get(r, uri_str, &buffer_chain);
00707
00708 if(rc != NGX_OK || buffer_chain == NULL)
00709 {
00710 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00711 "[xml_get_local_stylesheet] fileasync failed");
00712 return ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00713 "<b>XSL style sheet is unavailable</b> :: %s", sheet->res_uri);
00714 }
00715
00716 sheet->buffer_chain = buffer_chain;
00717
00718 rc = ngx_http_xslt2_xml_set_cached_stylesheet(r, sheet);
00719 if( rc != NGX_OK ) {
00720 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00721 "[xml_get_local_stylesheet] mxcache set request error");
00722 }
00723
00724 rc = ngx_http_xslt2_xml_parse_stylesheet(sheet);
00725 if(rc != NGX_OK)
00726 {
00727 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00728 "[xml_get_local_stylesheet] Parse style sheet error");
00729 return ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00730 "<b>Error during style sheet parsing</b> :: %s", sheet->res_uri);
00731 }
00732
00733 return ngx_http_xslt2_xml_apply_stylesheets(sheet->parent_xml);
00734 }
00735
00742 static ngx_int_t
00743 ngx_http_xslt2_xml_get_external_stylesheet(ngx_http_xslt2_sheet_t *sheet)
00744 {
00745 ngx_http_download_conn_t *dl_ctx;
00746 ngx_http_request_t *r;
00747 ngx_str_t *url;
00748 ngx_int_t rc;
00749 u_char *uri;
00750
00751 r = sheet->parent_xml->r;
00752 uri = sheet->res_uri;
00753
00754 dl_ctx = ngx_http_download_create_new(r);
00755
00756 dl_ctx->r = r;
00757 dl_ctx->data = sheet;
00758 dl_ctx->done_handler = ngx_http_xslt2_xml_download_handler;
00759
00760 sheet->download = dl_ctx;
00761
00762 url = ngx_pcalloc(r->pool, sizeof(ngx_str_t));
00763
00764 if(url == NULL) {
00765 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00766 "[xml_get_external_stylesheet] external style sheet loading failed");
00767 return ngx_http_xslt2_finalize_with_error(r,
00768 NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
00769 }
00770
00771 url->data = uri;
00772 url->len = strlen((char *) uri);
00773
00774 rc = ngx_http_download_parse_url(url, dl_ctx);
00775
00776 if(rc != NGX_OK)
00777 {
00778 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00779 "[xml_get_external_stylesheet] external style sheet loading failed");
00780 return ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00781 "<b>XSL Style sheet URL parsing failed</b> :: %s", sheet->res_uri);
00782 }
00783
00784 rc = ngx_http_download_enqueue(dl_ctx);
00785
00786 if(rc != NGX_OK && rc != NGX_AGAIN)
00787 {
00788 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00789 "[xml_get_external_stylesheet] external style sheet loading failed");
00790 return ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00791 "<b>XSL Style sheet is unavailable</b> :: %s", sheet->res_uri);
00792 }
00793
00794 sheet->parent_xml->dl_in_progress++;
00795
00796 return rc;
00797 }
00798
00805 static void
00806 ngx_http_xslt2_xml_download_handler(ngx_http_download_conn_t *dl_ctx)
00807 {
00808 ngx_http_xslt2_sheet_t *sheet;
00809 ngx_http_xslt2_xml_data_t *xml_data;
00810 ngx_http_request_t *r;
00811
00812 ngx_int_t headers_len;
00813 ngx_int_t rc;
00814
00815 sheet = dl_ctx->data;
00816 xml_data = sheet->parent_xml;
00817 r = xml_data->r;
00818
00819
00820 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00821 "[xml_stylesheet_ready]");
00822
00823 xml_data->dl_in_progress--;
00824 sheet->ready = 1;
00825
00826 if(dl_ctx->error != NGX_OK || dl_ctx->status != 200)
00827 {
00828 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00829 "[xml_stylesheet_ready] error during style sheet download :: %d", dl_ctx->error);
00830 ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00831 "<b>XSL style sheet download failed</b> :: %s", sheet->res_uri);
00832 return;
00833 }
00834
00835 if(dl_ctx->out_bufs == NULL ||
00836 dl_ctx->out_bufs->buf == NULL ||
00837 dl_ctx->out_bufs->buf->pos == NULL ||
00838 dl_ctx->body_start == NULL)
00839 {
00840 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00841 "[xml_stylesheet_ready] empty buffer");
00842 ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00843 "<b>XSL style sheet download failed</b> :: %s", sheet->res_uri);
00844 return;
00845 }
00846
00847 headers_len = dl_ctx->body_start - dl_ctx->out_bufs->buf->pos;
00848
00849 sheet->buffer_chain = dl_ctx->out_bufs;
00850 sheet->buffer_chain->buf->pos = dl_ctx->body_start;
00851
00852 rc = ngx_http_xslt2_xml_set_cached_stylesheet(r, sheet);
00853 if( rc != NGX_OK ) {
00854 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
00855 "[xml_stylesheet_ready] XCache set request error");
00856 }
00857
00858 rc = ngx_http_xslt2_xml_parse_stylesheet(sheet);
00859 if(rc != NGX_OK)
00860 {
00861 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
00862 "[xml_stylesheet_ready] parse style sheet error");
00863 ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00864 "<b>Error during style sheet parsing</b> :: %s", sheet->res_uri);
00865 return;
00866 }
00867
00868 ngx_http_xslt2_xml_apply_stylesheets(sheet->parent_xml);
00869 }
00870
00877 static ngx_int_t
00878 ngx_http_xslt2_xml_parse_stylesheet(ngx_http_xslt2_sheet_t *sheet)
00879 {
00880 ngx_chain_t *bc;
00881 ngx_buf_t *buf;
00882
00883 xmlDocPtr doc;
00884 xmlParserCtxtPtr ctxt;
00885 xsltStylesheetPtr xslt_sheet;
00886
00887 ngx_int_t rc;
00888
00889 ngx_http_xslt2_xml_data_t *xml_data;
00890
00891 xml_data = sheet->parent_xml;
00892
00893 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, xml_data->r->connection->log, 0,
00894 "[xml_parse_stylesheet]");
00895
00896 bc = sheet->buffer_chain;
00897
00898 ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
00899
00900 while(bc != NULL)
00901 {
00902 buf = bc->buf;
00903
00904 rc = xmlParseChunk(ctxt, (char *) buf->pos, (int) (buf->last - buf->pos),
00905 buf->last_buf || buf->last_in_chain);
00906
00907 if(rc != 0)
00908 return NGX_ERROR;
00909
00910 if(buf->last_buf)
00911 break;
00912
00913 bc = bc->next;
00914 }
00915
00916 doc = ctxt->myDoc;
00917
00918
00919 xmlFreeParserCtxt(ctxt);
00920
00921 if(doc == NULL)
00922 {
00923 ngx_log_error(NGX_LOG_ERR, xml_data->r->connection->log, 0,
00924 "[xml_parse_stylesheet] error during XML style sheet parsing");
00925 return NGX_ERROR;
00926 }
00927
00928 xslt_sheet = xsltParseStylesheetDoc(doc);
00929
00930 if(xslt_sheet == NULL)
00931 {
00932 ngx_log_error(NGX_LOG_ERR, xml_data->r->connection->log, 0,
00933 "[xml_parse_stylesheet] error during XSLT style sheet parsing");
00934 return NGX_ERROR;
00935 }
00936
00937 sheet->stylesheet = xslt_sheet;
00938
00939 return NGX_OK;
00940 }
00941
00950 static ngx_int_t
00951 ngx_http_xslt2_xml_apply_stylesheets(ngx_http_xslt2_xml_data_t *xml_data)
00952 {
00953 xmlDocPtr res;
00954
00955 xmlChar *buf;
00956 int len;
00957 ngx_int_t rc;
00958 ngx_chain_t *cl;
00959 ngx_http_request_t *r;
00960
00961 r = xml_data->r;
00962
00963 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, xml_data->r->connection->log, 0,
00964 "[xml_apply_stylesheets]");
00965
00966 if(xml_data->xml_ready == 0)
00967 {
00968 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, xml_data->r->connection->log, 0,
00969 "[xml_apply_stylesheets] XML is not ready to apply style sheets");
00970 return NGX_OK;
00971 }
00972
00973 if(xml_data->sheets == NULL)
00974 {
00975 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, xml_data->r->connection->log, 0,
00976 "[xml_apply_stylesheets] XML has no declared style sheets");
00977 return NGX_ERROR;
00978 }
00979
00980 while(xml_data->act_sheet)
00981 {
00982 if(xml_data->act_sheet->ready == 0)
00983 {
00984 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, xml_data->r->connection->log, 0,
00985 "[xml_apply_stylesheets] Style sheet [%d] is not ready yet", xml_data->act_sheet->id);
00986 return NGX_DONE;
00987 }
00988
00989 res = xsltApplyStylesheet(xml_data->act_sheet->stylesheet, xml_data->doc, NULL);
00990
00991 if(res == NULL)
00992 {
00993 ngx_log_error(NGX_LOG_ERR, xml_data->r->connection->log, 0,
00994 "[xml_apply_stylesheets] Application of style sheet :: %d failed", xml_data->act_sheet->id);
00995 return ngx_http_xslt2_finalize_with_error(r, NGX_ERROR,
00996 "<b>Application of XSL style sheet failed</b> :: %s", xml_data->act_sheet->res_uri);
00997 }
00998
00999 xmlFreeDoc(xml_data->doc);
01000 xml_data->doc = res;
01001
01002 xml_data->act_sheet = xml_data->act_sheet->next;
01003 }
01004
01005
01006
01007 rc = xsltSaveResultToString(&buf, &len, xml_data->doc, xml_data->sheets_tail->stylesheet);
01008
01009 if(rc != 0)
01010 {
01011 ngx_log_error(NGX_LOG_ERR, xml_data->r->connection->log, 0,
01012 "[xml_apply_stylesheets] xsltSaveResultToString failed");
01013 return ngx_http_xslt2_finalize_with_error(r,
01014 NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
01015 }
01016
01017 cl = ngx_pcalloc(xml_data->r->pool, sizeof(ngx_chain_t));
01018 if(cl == NULL)
01019 {
01020 ngx_log_error(NGX_LOG_ERR, xml_data->r->connection->log, 0,
01021 "[xml_apply_stylesheets] XML buffer chain allocation failed");
01022 return ngx_http_xslt2_finalize_with_error(r,
01023 NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
01024 }
01025
01026 cl->buf = ngx_pcalloc(xml_data->r->pool, sizeof(ngx_buf_t));
01027 if(cl->buf == NULL)
01028 {
01029 ngx_log_error(NGX_LOG_ERR, xml_data->r->connection->log, 0,
01030 "[xml_apply_stylesheets] XML buffer allocation failed");
01031 return ngx_http_xslt2_finalize_with_error(r,
01032 NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
01033 }
01034
01035 cl->buf->pos = ngx_pcalloc(xml_data->r->pool, sizeof(u_char)*(len + 1));
01036 if(cl->buf->pos == NULL)
01037 {
01038 ngx_log_error(NGX_LOG_ERR, xml_data->r->connection->log, 0,
01039 "[xml_apply_stylesheets] XML buffer content allocation failed");
01040 return ngx_http_xslt2_finalize_with_error(r,
01041 NGX_HTTP_INTERNAL_SERVER_ERROR, NULL);
01042 }
01043
01044 ngx_cpystrn(cl->buf->pos, (u_char *) buf, len+1);
01045
01046 cl->buf->last = cl->buf->pos + len;
01047 cl->buf->memory = 1;
01048 cl->buf->last_buf = cl->buf->last_in_chain = 1;
01049
01050 xml_data->buffer_chain = cl;
01051 xml_data->res_len = len;
01052
01053 xmlFree(buf);
01054
01055 xml_data->done = 1;
01056
01057 return ngx_http_xslt2_process_data(r);
01058 }
01059
01066 static void
01067 ngx_http_xslt2_xml_stylesheet_node(ngx_http_xslt2_xml_data_t *xml_data, const xmlChar *pidata)
01068 {
01069 ngx_http_xslt2_sheet_t *sheet;
01070 ngx_http_request_t *r;
01071
01072 const xmlChar *uri;
01073 const xmlChar *uri_end;
01074 u_char *res;
01075
01076 r = xml_data->r;
01077
01078
01079 if((uri = xmlStrstr(pidata, (xmlChar *)"href=\"")) == NULL)
01080 {
01081 ngx_log_error(NGX_LOG_ERR, xml_data->r->connection->log, 0,
01082 "[xml_stylesheet_node] style sheet loading failed");
01083 ngx_http_xslt2_xml_stylesheet_error(xml_data, "No href attribute in style sheet declaration");
01084 return;
01085 };
01086 uri += 6;
01087
01088 if((uri_end = xmlStrchr(uri, (xmlChar)'\"')) == NULL)
01089 {
01090 ngx_log_error(NGX_LOG_ERR, xml_data->r->connection->log, 0,
01091 "[xml_stylesheet_node] Style sheet loading failed");
01092 ngx_http_xslt2_xml_stylesheet_error(xml_data, "Broken href attribute in style sheet declaration");
01093 return;
01094 };
01095
01096 sheet = ngx_http_xslt2_xml_create_new_stylesheet(xml_data);
01097
01098 if(sheet == NULL)
01099 {
01100 ngx_log_error(NGX_LOG_ERR, xml_data->r->connection->log, 0,
01101 "[xml_stylesheet_node] Style sheet loading failed");
01102 ngx_http_xslt2_xml_stylesheet_error(xml_data, NULL);
01103 return;
01104 }
01105
01106 res = ngx_pcalloc(xml_data->r->pool, sizeof(u_char)*(uri_end - uri + 1));
01107 ngx_cpystrn(res, (u_char *) uri, uri_end - uri + 1);
01108
01109 sheet->res_uri = res;
01110
01111 ngx_http_xslt2_xml_get_stylesheet(sheet, XXSLT_USE_CACHE);
01112 }
01113
01122 static void
01123 ngx_http_xslt2_xml_stylesheet_error(ngx_http_xslt2_xml_data_t *xml_data, char *msg, ...)
01124 {
01125 va_list args;
01126 u_char err_msg[NGX_MAX_ERROR_STR];
01127 ngx_int_t n;
01128
01129 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, xml_data->r->connection->log, 0,
01130 "[xml_stylesheet_error] stylesheet error");
01131
01132 xml_data->stylesheet_err = NGX_HTTP_INTERNAL_SERVER_ERROR;
01133
01134 if(msg == NULL)
01135 {
01136 return;
01137 }
01138
01139 err_msg[0] = '\0';
01140 va_start(args, msg);
01141 n = (size_t) vsnprintf((char *) err_msg, NGX_MAX_ERROR_STR, msg, args);
01142 va_end(args);
01143 err_msg[n] = '\0';
01144
01145 xml_data->stylesheet_err_msg = ngx_pcalloc(xml_data->r->pool, sizeof(u_char)*(n+1));
01146
01147 if(xml_data->stylesheet_err_msg == NULL)
01148 {
01149 return;
01150 }
01151
01152 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, xml_data->r->connection->log, 0,
01153 "[xml_stylesheet_error] finished");
01154
01155 xml_data->stylesheet_err = NGX_ERROR;
01156 ngx_cpystrn(xml_data->stylesheet_err_msg, err_msg, n+1);
01157 }
01158
01159
01161 static void
01162 ngx_http_xslt2_xml_sax_processing_instruction(void *data, const xmlChar *target,
01163 const xmlChar *pidata)
01164 {
01165 ngx_http_xslt2_xml_data_t *xml_data = data;
01166
01167 if(xmlStrcmp(target, (xmlChar *) "xml-stylesheet") == 0) {
01168 ngx_http_xslt2_xml_stylesheet_node(xml_data, pidata);
01169 return;
01170 }
01171
01172 xml_data->sax->processingInstruction(xml_data->ctxt, target, pidata);
01173 }
01174
01175 static void
01176 ngx_http_xslt2_xml_sax_start_document(void *data)
01177 {
01178 ngx_http_xslt2_xml_data_t *xml_data = data;
01179
01180 xml_data->sax->startDocument(xml_data->ctxt);
01181 }
01182
01183 static void
01184 ngx_http_xslt2_xml_sax_end_document(void *data)
01185 {
01186 ngx_http_xslt2_xml_data_t *xml_data = data;
01187
01188 xml_data->sax->endDocument(xml_data->ctxt);
01189 }
01190
01191 static void
01192 ngx_http_xslt2_xml_sax_internal_subset(void *data, const xmlChar *name,
01193 const xmlChar *externalId, const xmlChar *systemId)
01194 {
01195 ngx_http_xslt2_xml_data_t *xml_data = data;
01196
01197 xml_data->sax->internalSubset(xml_data->ctxt, name, externalId, systemId);
01198 }
01199
01200 static void
01201 ngx_http_xslt2_xml_sax_external_subset(void *data, const xmlChar *name,
01202 const xmlChar *externalId, const xmlChar *systemId)
01203 {
01204
01205 }
01206
01207 static void
01208 ngx_http_xslt2_xml_sax_entity_decl(void *data, const xmlChar *name, int type,
01209 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
01210 {
01211 ngx_http_xslt2_xml_data_t *xml_data = data;
01212
01213
01214 xml_data->sax->entityDecl(xml_data->ctxt, name, type, publicId, systemId, content);
01215 }
01216
01217 static void
01218 ngx_http_xslt2_xml_sax_attribute_decl(void *data, const xmlChar *elem,
01219 const xmlChar *fullname, int type, int def, const xmlChar *defaultValue,
01220 xmlEnumerationPtr tree)
01221 {
01222 ngx_http_xslt2_xml_data_t *xml_data = data;
01223
01224
01225 xml_data->sax->attributeDecl(xml_data->ctxt, elem, fullname, type, def, defaultValue,
01226 tree);
01227 }
01228
01229 static void
01230 ngx_http_xslt2_xml_sax_element_decl(void *data, const xmlChar * name, int type,
01231 xmlElementContentPtr content)
01232 {
01233 ngx_http_xslt2_xml_data_t *xml_data = data;
01234
01235 xml_data->sax->elementDecl(xml_data->ctxt, name, type, content);
01236 }
01237
01238 static void
01239 ngx_http_xslt2_xml_sax_notation_decl(void *data, const xmlChar *name,
01240 const xmlChar *publicId, const xmlChar *systemId)
01241 {
01242 ngx_http_xslt2_xml_data_t *xml_data = data;
01243
01244 xml_data->sax->notationDecl(xml_data->ctxt, name, publicId, systemId);
01245 }
01246
01247 static void
01248 ngx_http_xslt2_xml_sax_unparsed_entity_decl(void *data, const xmlChar *name,
01249 const xmlChar *publicId, const xmlChar *systemId,
01250 const xmlChar *notationName)
01251 {
01252 ngx_http_xslt2_xml_data_t *xml_data = data;
01253
01254 xml_data->sax->unparsedEntityDecl(xml_data->ctxt, name, publicId, systemId,
01255 notationName);
01256 }
01257
01258 static void
01259 ngx_http_xslt2_xml_sax_start_element(void *data, const xmlChar *localname,
01260 const xmlChar *prefix, const xmlChar *URI, int nb_namespaces,
01261 const xmlChar **namespaces, int nb_attributes, int nb_defaulted,
01262 const xmlChar **attributes)
01263 {
01264 ngx_http_xslt2_xml_data_t *xml_data = data;
01265
01266
01267 xml_data->sax->startElementNs(xml_data->ctxt, localname, prefix, URI, nb_namespaces,
01268 namespaces, nb_attributes, nb_defaulted, attributes);
01269 }
01270
01271 static void
01272 ngx_http_xslt2_xml_sax_end_element(void *data,
01273 const xmlChar * localname ATTRIBUTE_UNUSED,
01274 const xmlChar * prefix ATTRIBUTE_UNUSED,
01275 const xmlChar * URI ATTRIBUTE_UNUSED)
01276 {
01277 ngx_http_xslt2_xml_data_t *xml_data = data;
01278
01279 xml_data->sax->endElementNs(xml_data->ctxt, localname, prefix, URI);
01280 }
01281
01282 static void
01283 ngx_http_xslt2_xml_sax_characters(void *data, const xmlChar *p, int len)
01284 {
01285 ngx_http_xslt2_xml_data_t *xml_data = data;
01286
01287 xml_data->sax->characters(xml_data->ctxt, p, len);
01288 }
01289
01290 static void
01291 ngx_http_xslt2_xml_sax_cdata_block(void *data, const xmlChar *p, int len)
01292 {
01293 ngx_http_xslt2_xml_data_t *xml_data = data;
01294
01295 xml_data->sax->cdataBlock(xml_data->ctxt, p, len);
01296 }
01297
01298 static xmlEntityPtr
01299 ngx_http_xslt2_xml_sax_get_entity(void *data, const xmlChar *name)
01300 {
01301 ngx_http_xslt2_xml_data_t *xml_data = data;
01302
01303
01304 return xml_data->sax->getEntity(xml_data->ctxt, name);
01305 }
01306
01307 static xmlEntityPtr
01308 ngx_http_xslt2_xml_sax_get_parameter_entity(void *data, const xmlChar *name)
01309 {
01310 ngx_http_xslt2_xml_data_t *xml_data = data;
01311
01312
01313 return xml_data->sax->getParameterEntity(xml_data->ctxt, name);
01314 }
01315
01316 static xmlParserInputPtr
01317 ngx_http_xslt2_xml_sax_resolve_entity(void *data, const xmlChar *publicId,
01318 const xmlChar *systemId)
01319 {
01320 ngx_http_xslt2_xml_data_t *xml_data = data;
01321
01322 return xml_data->sax->resolveEntity(xml_data->ctxt, publicId, systemId);
01323 }
01324
01325 static void
01326 ngx_http_xslt2_xml_sax_reference(void *data, const xmlChar *name)
01327 {
01328 ngx_http_xslt2_xml_data_t *xml_data = data;
01329
01330 xml_data->sax->reference(xml_data->ctxt, name);
01331 }
01332
01333 static void
01334 ngx_http_xslt2_xml_sax_comment(void *data, const xmlChar *value)
01335 {
01336 ngx_http_xslt2_xml_data_t *xml_data = data;
01337
01338 xml_data->sax->comment(xml_data->ctxt, value);
01339 }
01340
01341 static int
01342 ngx_http_xslt2_xml_sax_is_standalone(void *data)
01343 {
01344 ngx_http_xslt2_xml_data_t *xml_data = data;
01345
01346 return xml_data->sax->isStandalone(xml_data->ctxt);
01347 }
01348
01349 static int
01350 ngx_http_xslt2_xml_sax_has_internal_subset(void *data)
01351 {
01352 ngx_http_xslt2_xml_data_t *xml_data = data;
01353
01354 return xml_data->sax->hasInternalSubset(xml_data->ctxt);
01355 }
01356
01357 static int
01358 ngx_http_xslt2_xml_sax_has_external_subset(void *data)
01359 {
01360 ngx_http_xslt2_xml_data_t *xml_data = data;
01361
01362 return xml_data->sax->hasExternalSubset(xml_data->ctxt);
01363 }
01364
01365 static void ngx_cdecl
01366 ngx_http_xslt2_xml_sax_error(void *data, const char *msg, ...)
01367 {
01368 ngx_http_xslt2_xml_data_t *xml_data = data;
01369
01370 size_t n;
01371 va_list args;
01372 u_char buf[NGX_MAX_ERROR_STR];
01373
01374 buf[0] = '\0';
01375
01376 va_start(args, msg);
01377 n = (size_t) vsnprintf((char *) buf, NGX_MAX_ERROR_STR, msg, args);
01378 va_end(args);
01379
01380 while (--n && (buf[n] == CR || buf[n] == LF)) { }
01381
01382 xml_data->libxml_error = (char *) buf;
01383 }
01384