Mercurial > hg > nginx-vendor-1-0
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 | ad25218fd14b |
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); |