jdaugherty commented on PR #16786:
URL: https://github.com/apache/grails-core/pull/16786#issuecomment-6505548894

   > Requesting changes. My objection is to the approach more than to any one 
line.
   > 
   > The bug in #15851 is a task that outlives its request and then reads the 
recycled facade. The trigger is data binding asking `MimeTypeUtils` for the 
request's formats, which, as chrisala notes, the binder doesn't actually need. 
This PR fixes it by having the task read a reimplementation of 
`HttpServletRequest` once the request completes. That's about 2,500 lines of 
new main code (`CompletedHttpServletRequest`, `TaskRequest`, `DispatchView`, 
and a filter on every request). It covers body buffering, reader mark/reset and 
`\r` handling, RFC 850/asctime date parsing, forward-attribute shadowing, 
multipart stand-ins, and a read/write lock around every call a task makes on 
the request. Each of the seven review rounds found a new place where the copy 
differs from the live request, and each fix made the emulation bigger. I don't 
see that converging. Every container, wrapper and filter is another way for the 
copy to drift from the request it replaces, and this code would have to keep up 
 with all of them on 8.0.x.
   > 
   > Spring has already defined what a request looks like after it completes. 
Once `ServletRequestAttributes.requestCompleted()` has run, request-scope 
access throws `IllegalStateException("Cannot ask for request attribute - 
request is not active anymore!")`. hk2166's first proposal on the issue matches 
that: when the request completes, detach the task's web request. 
`GrailsWebRequest.lookup()` then returns null in the task, and code that can 
run without a request (binding, `MimeTypeUtils`, the binder's locale) falls 
back the way it already does on a plain background thread. That's also how 
`Promises.task` behaved in 7.x. Detaching keeps what this PR preserves while 
the request is still being processed: a `WebPromises.task` that renders while 
Spring MVC holds the request open, and `AsyncActionResultTransformer` reading 
`MODEL_AND_VIEW`. Both keep working because the task still has the request 
object itself until completion. Detaching also covers the response, which this 
PR leaves poi
 nting at the recycled facade (inline), and it needs no body buffering, no 
proxy, and no emulation that has to match the container.
   > 
   > @jdaugherty, you suggested a true copy on the issue. After how the rounds 
went, I'd rather go back to detaching: a task that outlives its request should 
behave like code outside a request, not like a second request. Is there a case 
you had in mind that only a copy covers?
   > 
   > If the copy stays, the inline comments are what I'd still need addressed. 
I confirmed two of them with a throwaway spec on 
[3847d6f](https://github.com/apache/grails-core/commit/3847d6f006e8e169ada96ee556e862da03aa4fa6):
   > 
   >     * An unread 1 MB `application/octet-stream` body, with a task started 
that never touches the request: the thread completing the request reads all 
1,048,576 bytes inside the filter chain. With a 16 MB body it reads 2,097,153 
bytes and keeps none of them.
   > 
   >     * Inside a task, while the request is still live, 
`org.springframework.web.util.WebUtils.getNativeRequest(request, 
MockHttpServletRequest)` returns `null`, and the task's request is no longer 
the request object. On 8.0.x it is.
   
   @codeconsole Yes, the reason I was suggesting a copy instead is because 
those requests are managed by the dispatcher, etc and are meant to be closed by 
the encompassing web request.  If we aren't copying, we've now got state being 
managed externally from the web thread process and there's a possibility we 
won't have centralized logic. Historically, these type of changes are sources 
of CVEs so copy seems like a more reasonable solution.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to