Skip to content

Add Content-Type directive to body factory .body_factory_info#12947

Draft
bryancall wants to merge 3 commits intoapache:masterfrom
bryancall:body-factory-content-type
Draft

Add Content-Type directive to body factory .body_factory_info#12947
bryancall wants to merge 3 commits intoapache:masterfrom
bryancall:body-factory-content-type

Conversation

@bryancall
Copy link
Contributor

@bryancall bryancall commented Mar 6, 2026

Problem

Body factory error responses are always served with Content-Type: text/html and there is no way to change this. The .body_factory_info metadata file supports Content-Language and Content-Charset directives but has no Content-Type directive. Operators who serve non-HTML error pages (plain text, JSON, etc.) have no mechanism to set the correct MIME type.

Additionally, HttpSM::setup_internal_transfer unconditionally overwrites Content-Type to text/html when internal_msg_buffer_type is NULL, which would mask any type set earlier in the response pipeline.

Summary

  • Add Content-Type directive to .body_factory_info -- Operators can now set the MIME type for body factory error responses (e.g. Content-Type: text/plain) instead of the hardcoded text/html default. The directive is parsed alongside the existing Content-Language and Content-Charset directives.

  • Fix Content-Type overwrite in HttpSM::setup_internal_transfer -- Now uses the MIME_PRESENCE_CONTENT_TYPE presence bit to only apply the text/html default when Content-Type is not already present in the response.

  • Add documentation for .body_factory_info metadata file -- The admin guide's error messages page now documents all three supported directives (Content-Language, Content-Charset, Content-Type) with examples.

  • Add autest -- New body_factory_content_type.test.py verifies both default (text/html) and custom (text/plain) Content-Type behavior.

Testing

  • Built with ASAN, tested manually (default and custom Content-Type verified via curl)
  • Autest passes: both default and custom Content-Type scenarios

Fixes: #10893

The body factory previously only supported Content-Language and
Content-Charset directives in .body_factory_info. This adds a
Content-Type directive so operators can control the MIME type of
error responses (e.g. text/plain instead of the default text/html).

Also fixes HttpSM::setup_internal_transfer which was unconditionally
overwriting Content-Type to text/html, masking any type set by the
body factory. Now uses the presence bit check to only set the default
when Content-Type is not already present in the response.
The :file: role with nitpicky mode causes an unresolved reference
warning for .body_factory_info. Use literal markup instead.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends Apache Traffic Server’s body factory error-page customization to support a configurable Content-Type via .body_factory_info, and prevents HttpSM from overwriting an already-set Content-Type during internal transfers.

Changes:

  • Add parsing/storage of a new Content-Type directive in .body_factory_info and use it when generating body-factory responses.
  • Update HttpSM::setup_internal_transfer() to only apply the text/html default when Content-Type is not already present.
  • Add documentation and a gold test covering both default and custom Content-Type behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/gold_tests/body_factory/body_factory_content_type.test.py New autest validating default (text/html) vs custom (text/plain) body-factory Content-Type.
src/proxy/http/HttpSM.cc Avoids unconditional Content-Type: text/html overwrite by checking the presence bit.
src/proxy/http/HttpBodyFactory.cc Parses Content-Type from .body_factory_info and incorporates it into generated response headers.
include/proxy/http/HttpBodyFactory.h Extends internal fabricate() signature and body set metadata to include content_type.
doc/admin-guide/monitoring/error-messages.en.rst Documents .body_factory_info directives, including the new Content-Type.
configs/body_factory/default/.body_factory_info Updates shipped template metadata comments to include the new directive.

You can also share your feedback on Copilot code review. Take the survey.

- Rename type_ptr to content_type_ptr to avoid confusion with the
  type parameter (error template name)
- Fix docs: .body_factory_info is required for a template set to load,
  not optional. Absent file causes the directory to be skipped.
- Use literal markup for .body_factory_info to fix Sphinx nitpick warning
@bryancall bryancall requested a review from Copilot March 9, 2026 15:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.


You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +185 to +186
const char *mime_type = content_type_ptr ? content_type_ptr : "text/html";
snprintf(content_type_out_buf, content_type_buf_size, "%s; charset=%s", mime_type, charset_ptr);
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Content-Type from .body_factory_info is appended with ; charset=... unconditionally. If an operator configures Content-Type with parameters (e.g. application/json; charset=utf-16), this will generate an invalid header with duplicate charset parameters. Consider either (a) treating .body_factory_info's Content-Type as the full header value and not appending charset, or (b) parsing/stripping parameters (or at least detecting an existing charset=) before appending.

Copilot uses AI. Check for mistakes.
Comment on lines +83 to +84
tr.Processes.Default.Streams.stdout += Testers.ContainsExpression(
'Content-Type: text/html; charset=utf-8', 'Default body factory should produce text/html with charset')
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assertion is potentially brittle if the server emits a different charset casing (e.g. UTF-8) or slightly different formatting/spacing. If ContainsExpression is regex-based, consider using a case-insensitive pattern and/or a more flexible match for the charset portion to reduce test flakiness across platforms/builds.

Copilot uses AI. Check for mistakes.

To describe Korean error pages encoded in the ``iso-2022-kr`` character set::

Content-Language: kr
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Content-Language: kr is not a standard language tag for Korean (commonly ko / ko-KR per BCP 47). Since this section is newly documenting metadata directives, consider updating the example to use a standard tag to avoid propagating incorrect configuration patterns.

Suggested change
Content-Language: kr
Content-Language: ko-KR

Copilot uses AI. Check for mistakes.
@bryancall bryancall marked this pull request as draft March 9, 2026 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Is there a way to customize body factory response headers?

2 participants