I was experimenting with the new support for declaring protocols for e.g.
ALPN, but with an SSL toolkit other than openssl. This one wants us to pass
the entire list of all the protocols the server supports in advance; later,
we can request the one protocol that the toolkit negotiated.
It looks like the protocol_propose hook allows us to only grab a subset of
the protocols - i.e. it expects us to have the protocol list that the
client sends us. I've attached a patch which modifies the protocol_propose
hook's interface (documentation), allowing us to get all of the protocols
supported by the server. I also modified h2's implementation of the hook to
reflect the interface change.
Let me know if anyone sees a problem.
diff --git a/include/http_protocol.h b/include/http_protocol.h
index 846df2f..b9e0fd4 100644
--- a/include/http_protocol.h
+++ b/include/http_protocol.h
@@ -719,11 +719,15 @@ AP_DECLARE_HOOK(apr_port_t,default_port,(const
request_rec *r))
*
* All hooks are run, unless one returns an error. Proposals may contain
* duplicates. The order in which proposals are added is usually ignored.
+ *
+ * If offers is NULL, then all protocols supported by the server will be
+ * added to the proposals array.
*
* @param c The current connection
* @param r The current request or NULL
* @param s The server/virtual host selected
- * @param offers A list of protocol identifiers offered by the client
+ * @param offers A list of protocol identifiers offered by the client, or
+ * NULL if the client doesn't know in advance
* @param proposals The list of protocol identifiers proposed by the hooks
* @return OK or DECLINED
*/
diff --git a/modules/http2/h2_switch.c b/modules/http2/h2_switch.c
index fd76983..a4cb909 100644
--- a/modules/http2/h2_switch.c
+++ b/modules/http2/h2_switch.c
@@ -105,9 +105,10 @@ static int h2_protocol_propose(conn_rec *c, request_rec *r,
while (*protos) {
/* Add all protocols we know (tls or clear) and that
- * were offered as options for the switch.
+ * were offered as options for the switch. If no
+ * options were offered, add everything.
*/
- if (ap_array_index(offers, *protos) >= 0) {
+ if (offers == NULL || ap_array_index(offers, *protos) >= 0) {
ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
"proposing protocol '%s'", *protos);
APR_ARRAY_PUSH(proposals, const char*) = *protos;