I would use some very simple encoding to pass HTTP
messages in OCP payload. Something along these lines:
<chunk-type> <chunk-length> <chunk-data>
where "chunk-type" can be either of
"headers": HTTP headers including the first line and the last
CRLF terminator
"trailers": HTTP trailers including the last CRLF terminator
"body": raw HTTP message payload
"all": raw HTTP message
and one OCP payload may contain several chunks in the
above format.
For a HTTP response we need the original HTTP request as additional
meta data. That needs to be added somehow.
Indeed, I forgot about that requirement. Will having both "request-*"
and "response-*" chunk types be too complicated?
request-headers, response-headers
request-trailers, response-trailers
request-body, response-body
request-all, response-all
(or the other way around: *-request and *-response).
First, I am not so sure about the "all" chunks. Do we really need them?
While having multiple options and being able to negotiate things is great,
especially for OCP core, I think that the application protocol bindings should
define a single way how to vector the data to the callout server.
If both OPES processor and callout server agree on HTTP/OCP they have to
understand at least the basics of that protocol and so being able to differ
between headers and bodies.
If actors in the OPES scenario cannot find a matching protocol binding that
both support, there could/should be a File/OCP and Raw-TCP/OCP that may work
out sometimes as fallback.
Second, is it necessary that the application procotol chunks encoding is
another abstraction layer on top of the data-have messages?
Why do we not just introduce a named parameter (Content-Type or Payload-Type)
for data-have and use this core message type to send the chunks? Chunk length
is then without additional cost and no extra encoding needs to be parsed.
The protocol binding will then define which payload types exist, whether there
is a given order and whether multiple data-have messages per payload type are
allowed.
We will also have to explicitly document what to do with 1xx HTTP/1.1
responses. It would be nice if we can adapt them, but I do not know
yet whether they have to be treated specially from HTTP binding point
of view.
Good point.
It probably makes no sense to handle a 1xx as its own transaction. It could be
another response header but we will need to explain this clearly in the draft
otherwise we will get interop problems because many implementations will
probably oversee this point.
Regarding the transfer encoding:
Seems that we agree that OPES processor and callout server will negotiate which
is supported; identity MUST be supported. OPES processor MAY/SHOULD have some
pre-processing to remove a transfer encoding that it supports but the callout
server doesn't.
Regarding content length and persistency:
We agree that the OPES processor is responsible to handle HTTP persistency and
that it is impossible to have a protocol which is so robust that it overcomes
all buggy implementations.
But I think that we can reduce the problem and enforce the OPES processor
responsibility by defining:
- the OPES processor MUST ignore the Content-Length header returned in the
response header chunk from the callout server
- a callout server SHOULD indicate the application message length via the
sizep parameter in the start-app-message if it is known at that time.
- the OPES processor SHOULD honor the sizep parameter and use it to adjust the
Content-Length header; otherwise it MUST remove the Content-Length header; it
MAY then switch to chunked transfer encoding if supported by the client for
being able to keep the HTTP connection alive.
With this approach many callout services that only concentrate on the HTTP body
can ignore the header and use data-as-is rather than parsing the header,
finding and adjusting the ContentLength header, reassembing the header and
sending it back.
What do you think about this?
Regards
Martin