Rick Potts wrote:
> Darin Fisher wrote:
>
>> Judson Valeski wrote:
>>
>>> Doug Turner wrote:
>>>
>>>> I proposed three changes which would address bidirectional IO on a channel. I
>>>> was under the impression you agreed that this approach was the best...?
>>>
>>>
>>> Your impression is correct. I completey support this solution for bidirectional
>>> asyncronous IO on a channel. My only objection is to the design detail (which will
>>> have semantic ramifications) of hanging the content-type off of the nsIStreamInfo.
>>> You're putting a 1-to-1 relationship on the content-type to request. Rick and I are
>>> arguing that there's a 1-to-1 relationship between content type and channel (not
>>> request which you can have multiple of per channel).
>>>
>>> nsIChannel(http://www.foo.com/) is always going to have just one content type,
>never
>>> two.
>>>
>>> Please illustrate under what circumbstances a nsIChannel implementation (transport
>>> layer, or protocol) would have a content type that would differ from one
>>> asyncRead|Write() to the next (bi directional or not). If you can point that case
>>> out, then indeed, content-type info would have to hang off of the request, I just
>>> don't see that case happening. And, if we do have that need, I'd argue the
>>> nsIChannel should not longer be the logical connection and that URI's should be per
>>> request as well. My point is that there's a 1-to-1 mapping between content type and
>>> URI (currently a channel is a logical connection extension of a URI), and hanging
>>> the content type off of the request breaks that model.
>>
>> Consider the implementation of a reusable server connection for protocol
>> foo, which is a nsIChannel. Various consumers of the server connection
>> may wish to issue requests and wait for a response. While issueing a
>> request, the server connection may be in the middle of processing a
>> response for a previously issued request. In this case, the
>> content-type of the data being read could very well differ from the
>> content-type of the data being written. Clearly the content-type of the
>> channel is not well defined in this case.
>>
>> So, the question then becomes: do we want to support such a design? I
>> say yes... especially since we can.
>>
>
> I don't understand this example... Are you saying that given the URI 'foo://bar' if
>the
> consumer does two consecutive reads, it will get back data with *different*
> content-types? I don't see how this is useful?
>
> It sounds sort of like connecting to the 'quote of the day' server (except for
>different
> content-types :-)
>
> I'm sure that we could invent some protocol which could do useful work using this
>model,
> but I don't see that any of the protocols which we currently support (or would want
>to
> support) require this feature...
>
> As far as I can see, the real question is whether a single URI can contain data of
> multiple content-types? My assumption is that there *is* a one-to-one mapping from
>a URI
> to a single content-type.
>
> In your example, if the multiple consumers are issuing requests of the same
>nsIChannel,
> then they *must* all be receiving data of the same content-type... So, as soon as
>the
> content-type is discovered it will be the same for all requests made to that channel.
>
> The only counter-example that I can think of is the 'multipart/x-mixed-replace' case,
> where each piece of the stream can have a different content-type... But even in this
> case, a single request could span multiple content-types (ie. you could read more
>than one
> part of the multipart response...).
>
> So, even in this situation, associating the content-type with the request, rather
>than the
> channel, does not solve a problem...
>
>
>> Moreover, there is no reason to force the assumption that the
>> content-type of a URI will never change. Consider a HTTP server
>> response that should not be cached. The URL could be
>> http://www.foo.com/bar. First, it could return XML, and then 5 seconds
>> later, it could return index.html. Until we have the headers from the
>> server, there is no way to know, so why lock ourselves into the
>> assumption that the content-type for a particular URL is static?
>>
>
> As far as I can see, by relocating the content-type you just 'move' the problem from
> nsIChannel to nsIRequest. In the first case, if you cache a given channel and
>assume its
> content-type remains constant after the connection has close it might be stale.
>
> The same is true in the second case, if you cache a given nsIRequest and assume its
> content-type remains constant after the connection has closed...
>
> In both cases, the state associated with a channel (or request) represents a
>snap-shot in
> time... The only way to "protect" consumers from this would be to invalidate all of
>the
> state attributes as soon as the connection is closed...
>
> I would argue that a better solution would allow consumers to determine whether a
> connection was still alive (and therefore have valid state...)
>
>> Consumers of nsIChannel should understand that without a successful
>> request, there is no way of knowing the content-type for a particular
>> URI. The best you can do (without a successful request) is to guess the
>> content-type using the MIME service.
>>
>
> I totally agree that for some protocols, until a connection has been established the
> content-type is not known... However, I don't see that moving the content-type into
> *every* request makes things better...
>
> In the current model, it is assumed that as soon as a consumer receives an
> OnStartRequest(...) the content-type is available from the channel... The same
>would be
> true if the content-type were accessed via nsIRequest.
>
> The difference is that moving the content-type into nsIRequest would still require
>each
> channel implementation to cache the content-type... And would require alot of work
> dealing with that situations where the content-type is accessed *after* a request has
> completed...
>
> In the end, it looks like alot of work that doesn't really solve any problems...
>
> -- rick
>
>>> Again, I agree that these changes need to land in order to get bi-directional io
>>> going, but I think the content-type is hanging off of the wrong object; the
>request.
>>> If it hangs off of the channel life is good.
>>>
>>>> this bug has quickly evolved into what I am trying to do:
>>>>
>>>> http://bugzilla.mozilla.org/show_bug.cgi?id=65272
>>>
>>>
>>> This bug is about getting bi-directional io going. I believe that's perfectly
>doable
>>> w/ out changing the content-type parent.
>>>
>>> Jud
>>>
>>>
>>>
Rick,
Thanks for your comments...
I understand what you are saying, but let me explain some of our
motivations for making these changes. The primary motivation in all of
this has been to define nsIChannel such that it would permit overlapped
read and write operations. This has meant that we've had to move
attributes that could have different values for read and write
operations off of nsIChannel and onto *something* particular to the
requested operation. We have added parameters to AsyncRead, AsyncWrite,
OpenInputStream, and OpenOutputStream for transferOffset and
transferCount. AsyncRead and AsyncWrite now return nsIRequest objects,
so that each operation has its own status and can be
suspended/resumed/canceled independently.
Consumers can QI the nsIRequest for different interfaces... to get more
information about the request. (In the synchronous case, consumers can
QI the nsIInputStream or nsIOutputStream for the same set of
interfaces.) Thinking that content-type/length would not necessarily be
the same for read and write operations, we created an interface,
nsIStreamContentInfo, that one could QI from nsIRequest, etc. This
interface provides content-type and content-length attributes. Channel
impl could choose not to impl this interface (eg. the socket transport).
So, why allow content-type to vary from request to request? The biggest
reason is not to differentiate multiple reads, but to differentiate the
content-type of a read from a write when both are happening at the same
time. What would GetContentType() mean if there is both an active read
and an active write? Is it correct to require both the content being
read and the content being written to be of the same type? It just
seems much cleaner to associate the content-type with the request...
especially given that the content-type is often determined per server
transaction.
Darin