Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rough in ORIGIN_SUPPORT #406

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
93 changes: 58 additions & 35 deletions draft-ietf-httpbis-origin-frame.md
@@ -1,6 +1,6 @@
---
title: The ORIGIN HTTP/2 Frame
abbrev: ORIGIN Frames
title: HTTP/2 Origin Control
abbrev: HTTP/2 Origin Control
docname: draft-ietf-httpbis-origin-frame-latest
date: 2017
category: std
Expand Down Expand Up @@ -34,8 +34,8 @@ informative:

--- abstract

This document specifies the ORIGIN frame for HTTP/2, to indicate what origins are available on a
given connection.
This document specifies a mechanism to indicate what origins are available on a given connection
when using HTTP/2.

--- note_Note_to_Readers

Expand All @@ -60,8 +60,8 @@ penalty of adding latency. To address that, this specification defines a new HTT

Additionally, experience has shown that HTTP/2's requirement to establish server authority using
both DNS and the server's certificate is onerous. This specification relaxes the requirement to
check DNS when the ORIGIN frame is in use. Doing so has additional benefits, such as removing the
latency associated with some DNS lookups.
check DNS when the ORIGIN frame is in use, as indicated by the "ORIGIN_SUPPORT" setting. Doing so
has additional benefits, such as removing the latency associated with some DNS lookups.


## Notational Conventions
Expand All @@ -72,6 +72,18 @@ as described in BCP 14 {{!RFC2119}} {{!RFC8174}} when, and only when, they appea
capitals, as shown here.


# The ORIGIN_SUPPORT HTTP/2 Setting {#setting}

The ORIGIN_SUPPORT HTTP/2 setting {{!RFC7540}}, Section 6.5) indicate that a server
desires the connection to be considered "opted in" to the behaviour described in this specification.

The value of the ORIGIN_SUPPORT setting does not have any meaning. Note that support for this
specification cannot be disabled once it is sent.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've used default = 0 and supported = 1 in the past. I think that I'd prefer that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That will cause people to assume they can turn it off; is it worth the added complexity / misunderstanding?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that's nasty. I don't know. Consistency is valuable though.

How about you mandate a value of 1. Anything else is an error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In HTTP/QUIC, it can be a Boolean (sent = true), but HTTP/2 has to have a value. I'm on the mandate-value-of-1 wagon.


ORIGIN_SUPPORT has no effect on servers, and MUST be ignored by them. Likewise, it MUST be ignored
by clients who have configured a proxy.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe what semantics you want to associate with the client sending the setting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has none, as above.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, ignored by servers. Yuck. Can we just make the server generate an error instead?


# The ORIGIN HTTP/2 Frame

The ORIGIN HTTP/2 frame ({{!RFC7540}}, Section 4) allows a server to indicate what origin(s)
Expand Down Expand Up @@ -113,12 +125,12 @@ define flags. See {{process}}.
The ORIGIN frame is a non-critical extension to HTTP/2. Endpoints that do not support this frame
can safely ignore it upon receipt.

When received by an implementing client, it is used to initialise and manipulate the Origin Set
(see {{set}}), thereby changing how the client establishes authority for origin servers (see
{{authority}}).
When received by an implementing client, it is used to manipulate the Origin Set (see {{set}}),
thereby changing how the client establishes authority for origin servers (see {{authority}}).

The origin frame MUST be sent on stream 0; an ORIGIN frame on any other stream is invalid and MUST
be ignored.
The ORIGIN frame MUST be sent on stream 0; an ORIGIN frame on any other stream is invalid and MUST
be ignored. The ORIGIN frame MUST be ignored if the ORIGIN_SUPPORT setting ({{setting}} has not be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/}}/}})/
s/not be/not been/

received.

Likewise, the ORIGIN frame is only valid on connections with the "h2" protocol identifier, or when
specifically nominated by the protocol's definition; it MUST be ignored when received on a
Expand Down Expand Up @@ -147,16 +159,16 @@ See {{algo}} for an illustrative algorithm for processing ORIGIN frames.
The set of origins (as per {{!RFC6454}}) that a given connection might be used for is known in this
specification as the Origin Set.

By default, the Origin Set for a connection is uninitialised. When an ORIGIN frame is first received
and successfully processed by a client, the connection's Origin Set is defined to contain an initial
origin. The initial origin is composed from:
By default, the Origin Set for a connection is uninitialised. When the ORIGIN setting ({{setting}})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you want to change the "By default" here too. Perhaps:

"On a connection where the server has not sent an ORIGIN_SUPPORT setting, the rules for authority in Section 9.1.2 of {{!RFC7540}} apply and the Origin Set is not used." ... or something.

s/ORIGIN/ORIGIN_SUPPORT/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll second that. If the server doesn't declare support, return to the RFC the server knows it's implementing.

is received by a client, the connection's Origin Set is defined to contain an initial origin. The
initial origin is composed from:

- Scheme: "https"
- Host: the value sent in Server Name Indication (SNI, {{!RFC6066}}, Section 3), converted to lower case
- Port: the remote port of the connection (i.e., the server's port)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I continue to be a little sad about the port's interaction with Alt-Svc. At this point, we're saying that the client opened the connection to speak to a particular origin (example.com:443) via an Alternative at a different port (alt.example.com:8443). So upon receipt of the server's settings, the connection will be valid for requests bound to https://example.com:8443, which is no outstanding request on the client, and the client can't legitimately make requests until it receives the ORIGIN frame.

If https://example.com:443 and https://example.com:8443 Alt-Svc to alt.example.com:8443, then the server can't know which origin the client thinks it's talking to except by the requests it makes. I still think I'd initialize this to the origin (including port) which prompted opening the connection, rather than the actual server port. The server doesn't necessarily need to know this value before the client makes a request.


The contents of that ORIGIN frame (and subsequent ones) allows the server to incrementally add new
origins to the Origin Set, as described in {{process}}.
The contents of subsequent ORIGIN frames allow the server to incrementally add new origins to the
Origin Set, as described in {{process}}.

The Origin Set is also affected by the 421 (Misdirected Request) response status code, defined in
{{!RFC7540}}, Section 9.1.2. Upon receipt of a response with this status code, implementing clients
Expand All @@ -165,19 +177,19 @@ Section 6.2) and remove it from the connection's Origin Set, if present.

Note:

: When sending an ORIGIN frame to a connection that is initialised as an Alternative Service
: When sending an ORIGIN setting on a connection that is initialised as an Alternative Service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ORIGIN_SUPPORT again

{{?RFC7838}}, the initial origin set ({{set}}) will contain an origin with the appropriate
scheme and hostname (since Alternative Services specifies that the origin's hostname be sent
in SNI). However, it is possible that the port will be different than that of the intended
origin, since the initial origin set is calculated using the actual port in use, which can be
different for the alternative service. In this case, the intended origin needs to be sent in
the ORIGIN frame explicitly.
a subsequent ORIGIN frame explicitly.

: For example, a client making requests for "https://example.com" is directed to an alternative
service at ("h2", "x.example.net", "8443"). If this alternative service sends an ORIGIN
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ORIGIN_SETTING

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ORIGIN_SUPPORT

frame, the initial origin will be "https://example.com:8443". The client will not be able to
setting, the initial origin will be "https://example.com:8443". The client will not be able to
use the alternative service to make requests for "https://example.com" unless that origin is
explicitly included in the ORIGIN frame.
explicitly included in an ORIGIN frame.


## Authority, Push and Coalescing with ORIGIN {#authority}
Expand All @@ -192,11 +204,11 @@ authoritative, both in HEADERS and PUSH_PROMISE frames from the server ({{!RFC75
generally only send requests on connections that they believe to be authoritative for the origin in
question.

Once an Origin Set has been initialised for a connection, clients that implement this specification
use it to help determine what the connection is authoritative for. Specifically, such clients MUST
NOT consider a connection to be authoritative for an origin not present in the Origin Set, and
SHOULD use the connection for all requests to origins in the Origin Set for which the connection is
authoritative, unless there are operational reasons for opening a new connection.
Once ORIGIN_SUPPORT has been received on a connection, clients that implement this specification
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Once the ORIGIN_SUPPORT setting has been received"

use the Origin Set to help determine what the connection is authoritative for. Specifically, such
clients MUST NOT consider a connection to be authoritative for an origin not present in the Origin
Set, and SHOULD use the connection for all requests to origins in the Origin Set for which the
connection is authoritative, unless there are operational reasons for opening a new connection.

Note that for a connection to be considered authoritative for a given origin, the client is still
required to obtain a certificate that passes suitable checks; see Section 9.1.1. of {{!RFC7540}}
Expand Down Expand Up @@ -224,6 +236,13 @@ This specification adds an entry to the "HTTP/2 Frame Type" registry.
* Code: 0xc
* Specification: [this document]

This specification adds an entry to the "HTTP/2 Settings" registry.

* Name: ORIGIN_SUPPORT
* Code: assign_me
* Initial Value: (any value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's follow convention and make the initial value 0.

* Specification: [this document]


# Security Considerations {#sc}

Expand All @@ -248,15 +267,19 @@ close the connection if it is too high.
--- back


# Non-Normative Processing Algorithm {#algo}
# Non-Normative Processing Algorithms {#algo}

The following algorithm illustrates how a client could handle received ORIGIN_SUPPORT settings:

1. Initialise the Origin Set as per {{set}}.

The following algorithm illustrates how a client could handle received ORIGIN frames:

1. If the client is configured to use a proxy for the connection, ignore the frame and stop processing.
2. If the connection is not identified with the "h2" protocol identifier or another protocol that has explicitly opted into this specification, ignore the frame and stop processing.
3. If the frame occurs upon any stream except stream 0, ignore the frame and stop processing.
4. If any of the flags 0x1, 0x2, 0x4 or 0x8 are set, ignore the frame and stop processing.
5. If no previous ORIGIN frame on the connection has reached this step, initialise the Origin Set as per {{set}}.
1. If the client has not received an ORIGIN_SUPPORT setting on the connection, ignore the frame and stop processing.
2. If the client is configured to use a proxy for the connection, ignore the frame and stop processing.
3. If the connection is not identified with the "h2" protocol identifier or another protocol that has explicitly opted into this specification, ignore the frame and stop processing.
4. If the frame occurs upon any stream except stream 0, ignore the frame and stop processing.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have it generate an error? Also, that suggests moving this step to the first step so that we can catch more errors.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Possibly. Which step is 'this'?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Step 4 (frame on streams other than 0)

5. If any of the flags 0x1, 0x2, 0x4 or 0x8 are set, ignore the frame and stop processing.
6. For each `Origin-Entry` in the frame payload:
1. Parse `ASCII-Origin` as an ASCII serialization of an origin ({{!RFC6454}}, Section 6.2) and let the result be `parsed_origin`. If parsing fails, skip to the next `Origin-Entry`.
5. Add `parsed_origin` to the Origin Set.
Expand All @@ -269,15 +292,15 @@ The set of origins advertised using this mechanism is under control of the serve
obligated to use it, or to advertise all origins which they might be able to answer a request for.

For example, it can be used to inform the client that the connection is to only be used for the
SNI-based origin, by sending an empty ORIGIN frame. Or, a larger number of origins can be indicated
by including a payload.
SNI-based origin, by sending only an ORIGIN_SUPPORT setting. Or, a larger number of origins can be
indicated by including one or more ORIGIN frames as well.

Generally, this information is most useful to send before sending any part of a response that might
initiate a new connection; for example, `Link` headers {{?RFC5988}} in a response HEADERS, or links
in the response body.

Therefore, the ORIGIN frame ought be sent as soon as possible on a connection, ideally before any
HEADERS or PUSH_PROMISE frames.
Therefore, the ORIGIN_SUPPORT setting and any ORIGIN frames ought be sent as soon as possible on a
connection, ideally before any HEADERS or PUSH_PROMISE frames.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that you want to point out that the ORIGIN_SUPPORT setting should be sent in the connection preface, and separately that ORIGIN frames need to be sent as early as possible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the behavior of late ORIGIN frames be defined? As I currently read the spec, the Origin set can be modified in the full stream lifetime, so even after HEADERS or PUSH_PROMISE frames.

When the server was unable to prepare the Origin frame (e.g. due to validation delays), can it send it anyway as hint for future requests?


However, if it's desirable to associate a large number of origins with a connection, doing so might
introduce end-user perceived latency, due to their size. As a result, it might be necessary to
Expand Down