Skip to content

[Bug]: html-to-pdf endpoint error on zip inputΒ #5534

@onief

Description

@onief

Installation Method

Local Installation

The Problem

When using Stirlings HTML-to-PDF abilities you get an error when trying to provide a zip-file which contains the html and its resources (e.g. css or images).

This should not be the case since the swagger-docu states "[/api/v1/convert/html/pdf] Convert an HTML or ZIP (containing HTML and CSS) to PDF".
It happens for both cases: Docker and Local Installation.

I investigated the case since I needed it for local testing. What happens is that Stirling calls WeasyPrint CLI with the whole zipped folder as arguments, whereas WeasyPrint only excepts the plain html.
I already realized a working solution for me, so I can directly raise a PR once I am assigned.

If I'm missing any crucial steps please let me now!

Version of Stirling-PDF

2.3.1 (newest commit at that time)

Last Working Version of Stirling-PDF

No response

Page Where the Problem Occurred

localhost:8080/api/v1/convert/html/pdf

Docker Configuration

-e SYSTEM_DISABLESANITIZE=true
(since I want my external css to be applied)

Relevant Log Output

11:53:08.923 [virtual-137] INFO  s.s.common.util.ProcessExecutor - Running command: weasyprint -e utf-8 -v --pdf-forms /var/folders/x1/g31nxx854k38jyfndl02w69r0000gp/T/stirling-pdf/stirling-pdf-10709287287484235973.zip /var/folders/x1/g31nxx854k38jyfndl02w69r0000gp/T/stirling-pdf/stirling-pdf-8799506396568818203.pdf
11:53:09.205 [Thread-38] INFO  s.s.common.util.ProcessExecutor - INFO: Step 1 - Fetching and parsing HTML - /var/folders/x1/g31nxx854k38jyfndl02w69r0000gp/T/stirling-pdf/stirling-pdf-10709287287484235973.zip
11:53:09.232 [Thread-38] INFO  s.s.common.util.ProcessExecutor - Traceback (most recent call last):
11:53:09.232 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/bin/weasyprint", line 7, in <module>
11:53:09.232 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     sys.exit(main())
11:53:09.232 [Thread-38] INFO  s.s.common.util.ProcessExecutor -              ~~~~^^
11:53:09.232 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/weasyprint/__main__.py", line 205, in main
11:53:09.232 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     html.write_pdf(output, **options)
11:53:09.232 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
11:53:09.232 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/weasyprint/__init__.py", line 270, in write_pdf
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     self.render(font_config, counter_style, color_profiles, **options)
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/weasyprint/__init__.py", line 226, in render
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     return Document._render(
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -            ~~~~~~~~~~~~~~~~^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -         self, font_config, counter_style, color_profiles, options)
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/weasyprint/document.py", line 249, in _render
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     context = cls._build_layout_context(
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -         html, font_config, counter_style, color_profiles, options)
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/weasyprint/document.py", line 225, in _build_layout_context
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     style_for = get_all_computed_styles(
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -         html, user_stylesheets, options['presentational_hints'], font_config,
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -         counter_style, color_profiles, page_rules, layers, target_collector,
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -         options['pdf_forms'])
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/weasyprint/css/__init__.py", line 1803, in get_all_computed_styles
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     for sheet in find_stylesheets(
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -                  ~~~~~~~~~~~~~~~~^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -             html.wrapper_element, html.media_type, html.url_fetcher,
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -             html.base_url, font_config, counter_style, color_profiles, page_rules,
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -             layers):
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -             ^^^^^^^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/weasyprint/css/__init__.py", line 268, in find_stylesheets
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     for wrapper in wrapper_element.query_all('style', 'link'):
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -                    ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/cssselect2/tree.py", line 272, in <genexpr>
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     if any(test(element) for test in tests))
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -        ^^^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/cssselect2/tree.py", line 272, in <genexpr>
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     if any(test(element) for test in tests))
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -            ~~~~^^^^^^^^^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "<string>", line 1, in <lambda>
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/[email protected]/3.14.2/Frameworks/Python.framework/Versions/3.14/lib/python3.14/functools.py", line 1126, in __get__
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     val = self.func(instance)
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/cssselect2/tree.py", line 307, in local_name
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     namespace_url, local_name = _split_etree_tag(self.etree_element.tag)
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -                                 ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -   File "/opt/homebrew/Cellar/weasyprint/67.0/libexec/lib/python3.14/site-packages/cssselect2/tree.py", line 377, in _split_etree_tag
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -     assert tag[0] == '{'
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor -            ^^^^^^^^^^^^^
11:53:09.233 [Thread-38] INFO  s.s.common.util.ProcessExecutor - AssertionError

Additional Information

No response

Browsers Affected

No response

No Duplicate of the Issue

  • I have verified that there are no existing issues raised related to my problem.

Metadata

Metadata

Assignees

Labels

Back EndIssues related to back-end developmentneeds investigationIssues that require further investigation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions