-
Notifications
You must be signed in to change notification settings - Fork 868
ORIGIN frame #1199
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
ORIGIN frame #1199
Conversation
This introduces a new option: `http2-origin-frame`. It can be either a scalar or a sequence. When this option is sent, H2O sends an ORIGIN frame as described here: https://github.com/httpwg/http-extensions/blob/master/draft-ietf-httpbis-origin-frame.md
|
Thank you for opening the PR and starting the discussion. It seems like that we need to consider how we should design the configuration directives for the frame. I do not have a concrete idea on how the design should be, but trying to find a good way to handle a configuration like below might be a good starting point. hosts:
a.example.com:
ssl:
port: 443
certificate-file: wildcard.example.com.crt
b.example.com:
ssl:
port: 443
certificate-file: wildcard.example.com.crt
c.example.org:
ssl:
port: 443
certificate-file: c.example.org.crt
"d.example.net:8443":
ssl:
port: 8443
certificate-file: d.example.net.crt
...For this example, an ORIGIN frame should not be sent when accepting a connection on port 443 with value of the SNI extension set to I am not sure what the correct answer would be, but looking at this example it seems that having a configuration directive for controlling ORIGIN frames next to |
Move the config logic under the ssl listener config
220e393 to
1194084
Compare
|
@kazuho thank you for your suggestion. 1194084 moves the config item under hosts:
a.example.com:
ssl:
port: 443
certificate-file: wildcard.example.com.crt
http2-origin-frame: "https://a.example.com"
b.example.com:
ssl:
port: 443
certificate-file: wildcard.example.com.crt
http2-origin-frame: [ "https://img.b.example.com", "https://b.example.com" ]
c.example.org:
ssl:
port: 443
certificate-file: c.example.org.crt
"d.example.net:8443":
ssl:
port: 8443
certificate-file: d.example.net.crt
...I think a remaining question is whether we want to handle the hosts:
*:
ssl:
port: 443
certificate-file: wildcard.example.com.crt
http2-origin-frame:
a.example.com: "https://a.example.com"But that might be overkill, what do you think? |
kazuho
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the updates. I think we are on the right track. I've left some (relatively minor) comments. Please let me know what you think.
lib/http2/connection.c
Outdated
| } | ||
|
|
||
| void h2o_http2_accept(h2o_accept_ctx_t *ctx, h2o_socket_t *sock, struct timeval connected_at) | ||
| void h2o_http2_accept(h2o_accept_ctx_t *ctx, h2o_socket_t *sock, h2o_iovec_t *http2_origin_frame, struct timeval connected_at) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to pass http2_origin_frame as a separate argument? To me, using the value in ctx seems fine.
include/h2o.h
Outdated
| struct { | ||
| SSL_CTX *ssl_ctx; | ||
| h2o_iovec_t *http2_origin_frame; | ||
| } ssl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not move ssl_ctx into a new field, but have both ssl_ctx and http2_origin_frame direct members of h2o_accept_ctx_t.
The reasons are: 1. the change would be smaller 2. in terms of protocol, origin frames can be sent even when SSL is not used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Regarding 2. my understanding of the RFC is that SSL has to be used?
src/main.c
Outdated
| h2o_strtolower(elems[i*2 + 1].base, elems[i*2 + 1].len); | ||
| } | ||
| http2_origin_frame = h2o_mem_alloc(sizeof(*http2_origin_frame)); | ||
| *http2_origin_frame = h2o_concat_list(NULL, elems, value->data.sequence.size * 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about creating a function that takes a list of strings to build the frame, instead of having duplicate code for YOML_TYPE_SCALAR and YOML_TYPE_SEQUENCE?
src/main.c
Outdated
| ssl_config->hostnames.entries[ssl_config->hostnames.size++] = h2o_iovec_init(host.base, host_end - host.base); | ||
| } | ||
|
|
||
| static h2o_iovec_t *build_http2_origin_frame(const h2o_iovec_t *origins, size_t nr_origins) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to change the signature of this function to: (h2o_configurator_command_t *cmd, yoml_t *origins, size_t nr_origins)?
If the argument to the directive was a scalar, the caller can just call build_http2_origin_frame(cmd, value, 1). If the argument to the directive was a sequence, the caller should call build_http2_origin_frame(cmd, value.data.sequence.elements, value.data.sequence.size).
|
@deweerdt Thank you very much. The code looks perfect! Let's keep this parked and merge it once we see the draft go forward and/or when we see clients start recognizing the frame. |
> The ORIGIN frame type is 0xc (decimal 12)
|
3b749c0 updates the branch to current master and updates the frame type to the latest draft (-04) |
|
@kazuho I've refreshed the PR to the latest master, as well as added test coverage. Since this is now RFC 8336 and there is Firefox support, i believe the PR should be considered for merging. |
|
Thank you for working on this issue and keeping it alive. |
This introduces a new option:
http2-origin-frame. It can be either ascalar or a sequence. When this option is sent, H2O sends an ORIGIN
frame as described here:
https://github.com/httpwg/http-extensions/blob/master/draft-ietf-httpbis-origin-frame.md
The PR is mostly intended to serve as basis for the discussion, rather than intended for merging. It feels like the contents of ORIGIN frame we send should actually depend on the SNI as follows:
h2o_conn_texpect_prefacelooks up the SNI inh2o_conn_tand using the config mapping, builds the ORIGIN frameThoughts?