comparison src/http/modules/ngx_http_xslt_filter_module.c @ 586:53f5f04a64b8 NGINX_0_8_45

nginx 0.8.45 *) Feature: ngx_http_xslt_filter improvements. Thanks to Laurence Rowe. *) Bugfix: SSI response might be truncated after include with wait="yes"; the bug had appeared in 0.7.25. Thanks to Maxim Dounin. *) Bugfix: the "listen" directive did not support the "setfib=0" parameter.
author Igor Sysoev <http://sysoev.ru>
date Tue, 13 Jul 2010 00:00:00 +0400
parents c456a023113c
children d0f7a625f27c
comparison
equal deleted inserted replaced
585:565a8b8fdad5 586:53f5f04a64b8
52 52
53 53
54 typedef struct { 54 typedef struct {
55 xmlDocPtr doc; 55 xmlDocPtr doc;
56 xmlParserCtxtPtr ctxt; 56 xmlParserCtxtPtr ctxt;
57 xmlSAXHandler *sax;
58 ngx_http_request_t *request; 57 ngx_http_request_t *request;
59 ngx_array_t params; 58 ngx_array_t params;
60 59
61 ngx_uint_t done; /* unsigned done:1; */ 60 ngx_uint_t done; /* unsigned done:1; */
62 } ngx_http_xslt_filter_ctx_t; 61 } ngx_http_xslt_filter_ctx_t;
66 ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b); 65 ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b);
67 static ngx_int_t ngx_http_xslt_add_chunk(ngx_http_request_t *r, 66 static ngx_int_t ngx_http_xslt_add_chunk(ngx_http_request_t *r,
68 ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b); 67 ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b);
69 68
70 69
71 static void ngx_http_xslt_sax_start_document(void *data);
72 static void ngx_http_xslt_sax_end_document(void *data);
73 static void ngx_http_xslt_sax_internal_subset(void *data, const xmlChar *name,
74 const xmlChar *externalId, const xmlChar *systemId);
75 static void ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name, 70 static void ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name,
76 const xmlChar *externalId, const xmlChar *systemId); 71 const xmlChar *externalId, const xmlChar *systemId);
77 static void ngx_http_xslt_sax_entity_decl(void *data, const xmlChar *name,
78 int type, const xmlChar *publicId, const xmlChar *systemId,
79 xmlChar *content);
80 static void ngx_http_xslt_sax_attribute_decl(void *data, const xmlChar *elem,
81 const xmlChar *fullname, int type, int def, const xmlChar *defaultValue,
82 xmlEnumerationPtr tree);
83 static void ngx_http_xslt_sax_element_decl(void *data, const xmlChar * name,
84 int type, xmlElementContentPtr content);
85 static void ngx_http_xslt_sax_notation_decl(void *data, const xmlChar *name,
86 const xmlChar *publicId, const xmlChar *systemId);
87 static void ngx_http_xslt_sax_unparsed_entity_decl(void *data,
88 const xmlChar *name, const xmlChar *publicId, const xmlChar *systemId,
89 const xmlChar *notationName);
90 static void ngx_http_xslt_sax_start_element(void *data,
91 const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI,
92 int nb_namespaces, const xmlChar **namespaces, int nb_attributes,
93 int nb_defaulted, const xmlChar **attributes);
94 static void ngx_http_xslt_sax_end_element(void *data,
95 const xmlChar * localname ATTRIBUTE_UNUSED,
96 const xmlChar * prefix ATTRIBUTE_UNUSED,
97 const xmlChar * URI ATTRIBUTE_UNUSED);
98 static void ngx_http_xslt_sax_characters(void *data, const xmlChar *p, int len);
99 static void ngx_http_xslt_sax_cdata_block(void *data, const xmlChar *p,
100 int len);
101 static xmlEntityPtr ngx_http_xslt_sax_get_entity(void *data,
102 const xmlChar *name);
103 static xmlEntityPtr ngx_http_xslt_sax_get_parameter_entity(void *data,
104 const xmlChar *name);
105 static xmlParserInputPtr ngx_http_xslt_sax_resolve_entity(void *data,
106 const xmlChar *publicId, const xmlChar *systemId);
107 static void ngx_http_xslt_sax_reference(void *data, const xmlChar *name);
108 static void ngx_http_xslt_sax_comment(void *data, const xmlChar *value);
109 static void ngx_http_xslt_sax_processing_instruction(void *data,
110 const xmlChar *target, const xmlChar *pidata);
111 static int ngx_http_xslt_sax_is_standalone(void *data);
112 static int ngx_http_xslt_sax_has_internal_subset(void *data);
113 static int ngx_http_xslt_sax_has_external_subset(void *data);
114 static void ngx_cdecl ngx_http_xslt_sax_error(void *data, const char *msg, ...); 72 static void ngx_cdecl ngx_http_xslt_sax_error(void *data, const char *msg, ...);
115 73
116 74
117 static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, 75 static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
118 ngx_http_xslt_filter_ctx_t *ctx); 76 ngx_http_xslt_filter_ctx_t *ctx);
364 322
365 static ngx_int_t 323 static ngx_int_t
366 ngx_http_xslt_add_chunk(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx, 324 ngx_http_xslt_add_chunk(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
367 ngx_buf_t *b) 325 ngx_buf_t *b)
368 { 326 {
369 int err; 327 int err;
370 xmlSAXHandler *sax; 328 xmlParserCtxtPtr ctxt;
371 xmlParserCtxtPtr ctxt;
372 329
373 if (ctx->ctxt == NULL) { 330 if (ctx->ctxt == NULL) {
374 331
375 ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); 332 ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
376 if (ctxt == NULL) { 333 if (ctxt == NULL) {
377 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 334 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
378 "xmlCreatePushParserCtxt() failed"); 335 "xmlCreatePushParserCtxt() failed");
379 return NGX_ERROR; 336 return NGX_ERROR;
380 } 337 }
381 338
382 ctx->sax = ngx_palloc(r->pool, sizeof(xmlSAXHandler)); 339 ctxt->sax->externalSubset = ngx_http_xslt_sax_external_subset;
383 if (ctx->sax == NULL) { 340 ctxt->sax->setDocumentLocator = NULL;
384 return NGX_ERROR; 341 ctxt->sax->warning = NULL;
385 } 342 ctxt->sax->error = ngx_http_xslt_sax_error;
386 343 ctxt->sax->fatalError = ngx_http_xslt_sax_error;
387 sax = ctxt->sax; 344 ctxt->sax->_private = ctx;
388
389 ngx_memcpy(ctx->sax, sax, sizeof(xmlSAXHandler));
390
391 sax->startDocument = ngx_http_xslt_sax_start_document;
392 sax->endDocument = ngx_http_xslt_sax_end_document;
393
394 sax->internalSubset = ngx_http_xslt_sax_internal_subset;
395 sax->externalSubset = ngx_http_xslt_sax_external_subset;
396 sax->entityDecl = ngx_http_xslt_sax_entity_decl;
397 sax->attributeDecl = ngx_http_xslt_sax_attribute_decl;
398 sax->elementDecl = ngx_http_xslt_sax_element_decl;
399 sax->notationDecl = ngx_http_xslt_sax_notation_decl;
400 sax->unparsedEntityDecl = ngx_http_xslt_sax_unparsed_entity_decl;
401 sax->setDocumentLocator = NULL;
402
403 sax->startElementNs = ngx_http_xslt_sax_start_element;
404 sax->endElementNs = ngx_http_xslt_sax_end_element;
405
406 sax->characters = ngx_http_xslt_sax_characters;
407 sax->ignorableWhitespace = ngx_http_xslt_sax_characters;
408 sax->cdataBlock = ngx_http_xslt_sax_cdata_block;
409 sax->getEntity = ngx_http_xslt_sax_get_entity;
410 sax->resolveEntity = ngx_http_xslt_sax_resolve_entity;
411 sax->getParameterEntity = ngx_http_xslt_sax_get_parameter_entity;
412 sax->reference = ngx_http_xslt_sax_reference;
413 sax->comment = ngx_http_xslt_sax_comment;
414 sax->processingInstruction = ngx_http_xslt_sax_processing_instruction;
415
416 sax->isStandalone = ngx_http_xslt_sax_is_standalone;
417 sax->hasInternalSubset = ngx_http_xslt_sax_has_internal_subset;
418 sax->hasExternalSubset = ngx_http_xslt_sax_has_external_subset;
419
420 sax->warning = NULL;
421 sax->error = ngx_http_xslt_sax_error;
422 sax->fatalError = ngx_http_xslt_sax_error;
423
424 ctxt->userData = ctx;
425
426 ctxt->replaceEntities = 1; 345 ctxt->replaceEntities = 1;
427 ctxt->loadsubset = 1; 346 ctxt->loadsubset = 1;
428 347
429 ctx->ctxt = ctxt; 348 ctx->ctxt = ctxt;
430 ctx->request = r; 349 ctx->request = r;
444 return NGX_ERROR; 363 return NGX_ERROR;
445 } 364 }
446 365
447 366
448 static void 367 static void
449 ngx_http_xslt_sax_start_document(void *data)
450 {
451 ngx_http_xslt_filter_ctx_t *ctx = data;
452
453 ctx->sax->startDocument(ctx->ctxt);
454 }
455
456
457 static void
458 ngx_http_xslt_sax_end_document(void *data)
459 {
460 ngx_http_xslt_filter_ctx_t *ctx = data;
461
462 ctx->sax->endDocument(ctx->ctxt);
463 }
464
465
466 static void
467 ngx_http_xslt_sax_internal_subset(void *data, const xmlChar *name,
468 const xmlChar *externalId, const xmlChar *systemId)
469 {
470 ngx_http_xslt_filter_ctx_t *ctx = data;
471
472 ctx->sax->internalSubset(ctx->ctxt, name, externalId, systemId);
473 }
474
475
476 static void
477 ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name, 368 ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name,
478 const xmlChar *externalId, const xmlChar *systemId) 369 const xmlChar *externalId, const xmlChar *systemId)
479 { 370 {
480 ngx_http_xslt_filter_ctx_t *ctx = data; 371 xmlParserCtxtPtr ctxt = data;
481 372
482 xmlDocPtr doc; 373 xmlDocPtr doc;
483 xmlDtdPtr dtd; 374 xmlDtdPtr dtd;
484 ngx_http_request_t *r; 375 ngx_http_request_t *r;
376 ngx_http_xslt_filter_ctx_t *ctx;
485 ngx_http_xslt_filter_loc_conf_t *conf; 377 ngx_http_xslt_filter_loc_conf_t *conf;
486 378
379 ctx = ctxt->sax->_private;
487 r = ctx->request; 380 r = ctx->request;
488 381
489 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); 382 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module);
490 383
491 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 384 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
492 "xslt filter extSubset: \"%s\" \"%s\" \"%s\"", 385 "xslt filter extSubset: \"%s\" \"%s\" \"%s\"",
493 name ? name : (xmlChar *) "", 386 name ? name : (xmlChar *) "",
494 externalId ? externalId : (xmlChar *) "", 387 externalId ? externalId : (xmlChar *) "",
495 systemId ? systemId : (xmlChar *) ""); 388 systemId ? systemId : (xmlChar *) "");
496 389
497 doc = ctx->ctxt->myDoc; 390 doc = ctxt->myDoc;
498 391
499 #if (NGX_HTTP_XSLT_REUSE_DTD) 392 #if (NGX_HTTP_XSLT_REUSE_DTD)
500 393
501 dtd = conf->dtd; 394 dtd = conf->dtd;
502 395
520 413
521 doc->extSubset = dtd; 414 doc->extSubset = dtd;
522 } 415 }
523 416
524 417
525 static void
526 ngx_http_xslt_sax_entity_decl(void *data, const xmlChar *name, int type,
527 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
528 {
529 ngx_http_xslt_filter_ctx_t *ctx = data;
530
531 ctx->sax->entityDecl(ctx->ctxt, name, type, publicId, systemId, content);
532 }
533
534
535 static void
536 ngx_http_xslt_sax_attribute_decl(void *data, const xmlChar *elem,
537 const xmlChar *fullname, int type, int def, const xmlChar *defaultValue,
538 xmlEnumerationPtr tree)
539 {
540 ngx_http_xslt_filter_ctx_t *ctx = data;
541
542 ctx->sax->attributeDecl(ctx->ctxt, elem, fullname, type, def, defaultValue,
543 tree);
544 }
545
546
547 static void
548 ngx_http_xslt_sax_element_decl(void *data, const xmlChar * name, int type,
549 xmlElementContentPtr content)
550 {
551 ngx_http_xslt_filter_ctx_t *ctx = data;
552
553 ctx->sax->elementDecl(ctx->ctxt, name, type, content);
554 }
555
556
557 static void
558 ngx_http_xslt_sax_notation_decl(void *data, const xmlChar *name,
559 const xmlChar *publicId, const xmlChar *systemId)
560 {
561 ngx_http_xslt_filter_ctx_t *ctx = data;
562
563 ctx->sax->notationDecl(ctx->ctxt, name, publicId, systemId);
564 }
565
566
567 static void
568 ngx_http_xslt_sax_unparsed_entity_decl(void *data, const xmlChar *name,
569 const xmlChar *publicId, const xmlChar *systemId,
570 const xmlChar *notationName)
571 {
572 ngx_http_xslt_filter_ctx_t *ctx = data;
573
574 ctx->sax->unparsedEntityDecl(ctx->ctxt, name, publicId, systemId,
575 notationName);
576 }
577
578
579 static void
580 ngx_http_xslt_sax_start_element(void *data, const xmlChar *localname,
581 const xmlChar *prefix, const xmlChar *URI, int nb_namespaces,
582 const xmlChar **namespaces, int nb_attributes, int nb_defaulted,
583 const xmlChar **attributes)
584 {
585 ngx_http_xslt_filter_ctx_t *ctx = data;
586
587 ctx->sax->startElementNs(ctx->ctxt, localname, prefix, URI, nb_namespaces,
588 namespaces, nb_attributes, nb_defaulted, attributes);
589 }
590
591
592 static void
593 ngx_http_xslt_sax_end_element(void *data,
594 const xmlChar * localname ATTRIBUTE_UNUSED,
595 const xmlChar * prefix ATTRIBUTE_UNUSED,
596 const xmlChar * URI ATTRIBUTE_UNUSED)
597 {
598 ngx_http_xslt_filter_ctx_t *ctx = data;
599
600 ctx->sax->endElementNs(ctx->ctxt, localname, prefix, URI);
601 }
602
603
604 static void
605 ngx_http_xslt_sax_characters(void *data, const xmlChar *p, int len)
606 {
607 ngx_http_xslt_filter_ctx_t *ctx = data;
608
609 ctx->sax->characters(ctx->ctxt, p, len);
610 }
611
612
613 static void
614 ngx_http_xslt_sax_cdata_block(void *data, const xmlChar *p, int len)
615 {
616 ngx_http_xslt_filter_ctx_t *ctx = data;
617
618 ctx->sax->cdataBlock(ctx->ctxt, p, len);
619 }
620
621
622 static xmlEntityPtr
623 ngx_http_xslt_sax_get_entity(void *data, const xmlChar *name)
624 {
625 ngx_http_xslt_filter_ctx_t *ctx = data;
626
627 return ctx->sax->getEntity(ctx->ctxt, name);
628 }
629
630
631 static xmlEntityPtr
632 ngx_http_xslt_sax_get_parameter_entity(void *data, const xmlChar *name)
633 {
634 ngx_http_xslt_filter_ctx_t *ctx = data;
635
636 return ctx->sax->getParameterEntity(ctx->ctxt, name);
637 }
638
639
640 static xmlParserInputPtr
641 ngx_http_xslt_sax_resolve_entity(void *data, const xmlChar *publicId,
642 const xmlChar *systemId)
643 {
644 ngx_http_xslt_filter_ctx_t *ctx = data;
645
646 return ctx->sax->resolveEntity(ctx->ctxt, publicId, systemId);
647 }
648
649
650 static void
651 ngx_http_xslt_sax_reference(void *data, const xmlChar *name)
652 {
653 ngx_http_xslt_filter_ctx_t *ctx = data;
654
655 ctx->sax->reference(ctx->ctxt, name);
656 }
657
658
659 static void
660 ngx_http_xslt_sax_comment(void *data, const xmlChar *value)
661 {
662 ngx_http_xslt_filter_ctx_t *ctx = data;
663
664 ctx->sax->comment(ctx->ctxt, value);
665 }
666
667
668 static void
669 ngx_http_xslt_sax_processing_instruction(void *data, const xmlChar *target,
670 const xmlChar *pidata)
671 {
672 ngx_http_xslt_filter_ctx_t *ctx = data;
673
674 ctx->sax->processingInstruction(ctx->ctxt, target, pidata);
675 }
676
677
678 static int
679 ngx_http_xslt_sax_is_standalone(void *data)
680 {
681 ngx_http_xslt_filter_ctx_t *ctx = data;
682
683 return ctx->sax->isStandalone(ctx->ctxt);
684 }
685
686
687 static int
688 ngx_http_xslt_sax_has_internal_subset(void *data)
689 {
690 ngx_http_xslt_filter_ctx_t *ctx = data;
691
692 return ctx->sax->hasInternalSubset(ctx->ctxt);
693 }
694
695
696 static int
697 ngx_http_xslt_sax_has_external_subset(void *data)
698 {
699 ngx_http_xslt_filter_ctx_t *ctx = data;
700
701 return ctx->sax->hasExternalSubset(ctx->ctxt);
702 }
703
704
705 static void ngx_cdecl 418 static void ngx_cdecl
706 ngx_http_xslt_sax_error(void *data, const char *msg, ...) 419 ngx_http_xslt_sax_error(void *data, const char *msg, ...)
707 { 420 {
708 ngx_http_xslt_filter_ctx_t *ctx = data; 421 xmlParserCtxtPtr ctxt = data;
709 422
710 size_t n; 423 size_t n;
711 va_list args; 424 va_list args;
712 u_char buf[NGX_MAX_ERROR_STR]; 425 ngx_http_xslt_filter_ctx_t *ctx;
426 u_char buf[NGX_MAX_ERROR_STR];
427
428 ctx = ctxt->sax->_private;
713 429
714 buf[0] = '\0'; 430 buf[0] = '\0';
715 431
716 va_start(args, msg); 432 va_start(args, msg);
717 n = (size_t) vsnprintf((char *) buf, NGX_MAX_ERROR_STR, msg, args); 433 n = (size_t) vsnprintf((char *) buf, NGX_MAX_ERROR_STR, msg, args);