[jsr356-experts] Re: [jsr356-users] Buffer sizes

From: Scott Ferguson <ferg_at_caucho.com>
Date: Tue, 29 Jan 2013 07:53:04 -0800

On 1/29/13 1:42 AM, Mark Thomas wrote:
> On 29/01/2013 00:16, Scott Ferguson wrote:
>> Fragments are not visible to the application. The Javadoc should never
>> refer to fragments.
> Fragments are visible to the application. The Javadoc for
> MessageHandler.Async<T> makes clear that the partial messages are fragments.

Those callbacks are not necessarily IETF 6455 fragments. An
implementation could use a fixed 256-byte
buffer to build each Async.onMessage.

IETF 6455 fragments are not visible to the application for the same
reason that TCP packets
are not visible to applications.

socket.read() might happen to return buffers that correspond to the TCP
packets, but the
application cannot rely on that behavior.
>>> Getting back to the original question, I still don't see a way of
>>> sending a fragment larger than Integer.MAX_VALUE through the API except
>>> through a Writer or OutputStream and even then buffering the content (as
>>> the size has to be known before the fragment can be sent) for fragments
>>> larger than Integer.MAX_VALUE is going to be a challenge.
>> Since applications don't send fragments, this doesn't make much sense.
>> The limits in Session and WebSocketContainer are for incoming messages,
>> not outgoing messages.
> I don't see anything in the Javadoc or the specification document that
> states that the limit only applies to incoming messages. If that was the
> intention, it needs to be made clear.

There's no point of specifying buffer sizes on outgoing messages,
because the implementation
could choose to use a fixed 256 byte buffer if it wished.
>>> Is it not reasonable to limit fragment sizes supported by this API to
>>> Integer.MAX_VALUE?
>> Again, fragments are not visible to this API.
> Again, they are.

Nope. Protocols like TCP and WebSockets and HTTP don't make their
internal fragmentation visible to applications for good reasons.

 From RFC6455:

    Unless specified otherwise by an extension, frames have _no_semantic
    meaning_. An intermediary might coalesce and/or split frames, if no
    extensions were negotiated by the client and the server or if some
    extensions were negotiated, but the intermediary understood all the
    extensions negotiated and knows how to coalesce and/or split frames
    in the presence of these extensions. One implication of this is that
    in absence of extensions, senders and receivers _must_not_depend_ on
    the presence of specific frame boundaries.

>> What would be the value of using an int instead of a long? It doesn't
>> save memory or affect performance.
> My point is that there is no way to pass a String, byte[] or ByteBuffer
> longer than Integer.MAX_VALUE so why even allow the limit to be set
> above that?
Outgoing doesn't matter. Think about it.
> It doesn't make sense to put limits on the length of a message because
> RFC6455 does not put any limits on message length.
Well, technically true, but a 2^63 long isn't a limit in any practical

> The limit in RFC6455
> is on fragment size which is 2^63-1 (Long.MAX_VALUE). While my
> preference would be to use the limit from RFC6455 I don't believe it is
> practical to do so in a Java implementation. The practical limit is
> Integer.MAX_VALUE.

The limits are for DOS issues.

The 2^63 limit was specifically for sendfile. There are files larger
than 2G. The current draft doesn't
have a sendfile call, but a future one could.

long isn't a practical limit because it's not possible to send 2^63 bytes.

-- Scott

> Mark