On 25/04/2019 21:16, Christopher Schultz wrote:
> Mark,
> 
> On 4/25/19 15:55, Mark Thomas wrote:
>> On 23/04/2019 16:29, Olivier Jaquemet wrote:
>>> On 23/04/2019 16:12, Christopher Schultz wrote:
>>>> On 4/23/19 05:58, Olivier Jaquemet wrote:
> 
>> <snip/>
> 
>>>>> * Add the following directive to context.xml : <Resources 
>>>>> cachingAllowed="false" />
>>>> Okay. Why context.xml, by the way?
>>> I don't even know (yet...) why this setting was added in the
>>> first place in the environment where it was present... ! so why
>>> this file... I don't know either :)
> 
>> DefaultServlet is assuming caching is in place. If you disable it,
>> you hit this issue.
> 
>>>>> * Create a large file in the samples webapp, for example :
>>>>> cd webapps/examples dd if=/dev/zero of=large.txt bs=1k
>>>>> count=2000000
> 
>> <snip/>
> 
>>>> Reading the code for FileResource.getContent, it's clear that
>>>> the entire file is being loaded into memory, which obviously
>>>> isn't going to work, here. I'm wondering why that's happening
>>>> since streaming is the correct behavior when caching=false.
>>>> Also strange is that DefaultServlet will attempt to call
>>>> FileResource.getContent() -- which returns a byte[] -- and, if
>>>> that returns null, it will call FileResource.getInputStream
>>>> which ... calls this.getContent. So this looks like a
>>>> special-case for FileResource just trying to implement that
>>>> interface in the simplest way possible.
> 
>> It is assuming it is working with a CachedResource instance rather
>> than directly with a FileResource instance.
> 
>>>> FileResource seems to implement in-memory caching whether it's
>>>> enabled or not.
>>>>
>>>> I can't understand why this doesn't fail for the other kind of 
>>>> connector. Everything else is the same? You have two separate 
>>>> connectors in one instance, or are you changing the connector
>>>> between tests?
>>>
>>> Everything is exactly the same as I have only one instance with
>>> two separate connectors (AJP+HTTP).
> 
>> I suspect HTTP avoids it because sendfile is enabled.
> 
>> The DefaultServlet logic needs a little refactoring.
> 
> And maybe FileResource, too?
> 
> I wasn't able to follow the logic of whether caching or not caching
> was enabled. I only did cursory checking, but it seemed like none of
> the resources implementations included any caching-aware code at all.
> Was I looking in the wrong place?

Don't think so. When caching is enabled everything gets wrapped in
CachedResource.

> If the resources are caching-aware, then I think the DefaultServlet
> can just always use Resource.getInputStream.
> 
> Hmm. That might cause a lot of unnecessary IO if the bytes are
> actually available.

That is a very tempting solution. The result is a LOT cleaner than the
patch I just wrote. CachingResource is smart enough to cache the bytes
and wrap them in a ByteArrayInputStream if Resource.getInputStream is
called. My only concern is I think this introduces and additional copy
of the data. I need to check that.

> Maybe when caching is disabled, we need to wrap resources in an
> UncachedResource object which always returns null from getContent()
> and forces the use of an InputStream?

My instinct is that would be too much but I'll keep it in mind in case I
end up in a logic hole that that digs me out of.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to