[MAGNOLIA-3014] call to response.getOutputStream() during the rendering process fails Created: 19/Jan/10  Updated: 20/Feb/15  Resolved: 09/Nov/10

Status: Closed
Project: Magnolia
Component/s: None
Affects Version/s: 4.2
Fix Version/s: 4.4

Type: Bug Priority: Major
Reporter: Philipp Bärfuss Assignee: Tobias Mattsson
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
causality
is causing MGNLPCK-39 Backup right menu item does not work ... Closed
relation
is related to MAGNOLIA-2989 GZipFilter causes "getWriter() has al... Closed
supersession
Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Bug DoR:
[ ]* Steps to reproduce, expected, and actual results filled
[ ]* Affected version filled
Date of First Response:

 Description   

After the refactoring of the renderers in 4.0 we pass now the writer directly to the renderer. Which is done by calling response.getWriter(). This is very useful as this makes the rendering in general independent of the servlet API and allows direct calls to the rendering engine by Java code (for instance servlets or tests).

Unfortunately a later call to response.getOutputStream() will fail as this violates the Servlet API specifications. There are several solutions possible.

Workaround: registering your custom servlet (at the servlets filter) and let the request be rendered by the servlet and not by the rendering filter

A) Pass a lazy wrapper instead of the writer
instead of passing the writer we pass a lazy wrapper which will call response.getWriter() only once the first operation is performed on the writer

  • not very transparent
    + no changes in the API needed

B) Change the API
Support both variations of renderers. This can be achieved by various ways
B.1) pass a object (magnolia response?) providing both methods which delegate to the response
B.2) have two methods render(.., writer) and render(.. stream) (most likely by having two interfaces)



 Comments   
Comment by Philipp Bärfuss [ 19/Jan/10 ]

I think this issue is not really related to MAGNOLIA-2989 but we might want to double check that.

Comment by Magnolia International [ 26/Mar/10 ]

Couldn't this be solved by using info.magnolia.module.cache.filter.CacheResponseWrapper (or similar) ?

It's currently only used when caching content (info.magnolia.module.cache.executor.Store) and by the GZipFilter.

Which you actually only run into this sort of issue when you're not caching (which is the case in the in the linked support issue, see executor.Bypass.processCacheReques in the stacktrace), which is an ugly side-effect.

Comment by Philipp Bärfuss [ 29/Mar/10 ]

As far I understand the CacheResponseWrapper would solve the issue by:

  • always use the output stream (never call getWriter() on the wrapped request)
  • getWriter() creates a independent writer wrapping the output stream

So yes this is a solution

C) use a response wrapper (similar or same as CacheResponseWrapper)

If we don't want to change the API this is probably the favored solution. But we would violate the servlet spec. Considering the fact that the cache already does the same it is acceptable for me.

Generated at Mon Feb 12 03:42:20 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.