| 50 | } |
| 51 | |
| 52 | static int h2_protocol_propose(conn_rec *c, request_rec *r, |
| 53 | server_rec *s, |
| 54 | const apr_array_header_t *offers, |
| 55 | apr_array_header_t *proposals) |
| 56 | { |
| 57 | int proposed = 0; |
| 58 | int is_tls = ap_ssl_conn_is_ssl(c); |
| 59 | const char **protos = is_tls? h2_protocol_ids_tls : h2_protocol_ids_clear; |
| 60 | |
| 61 | if (!h2_mpm_supported()) { |
| 62 | return DECLINED; |
| 63 | } |
| 64 | |
| 65 | if (strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))) { |
| 66 | /* We do not know how to switch from anything else but http/1.1. |
| 67 | */ |
| 68 | ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03083) |
| 69 | "protocol switch: current proto != http/1.1, declined"); |
| 70 | return DECLINED; |
| 71 | } |
| 72 | |
| 73 | if (!h2_protocol_is_acceptable_c1(c, r, 0)) { |
| 74 | ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(03084) |
| 75 | "protocol propose: connection requirements not met"); |
| 76 | return DECLINED; |
| 77 | } |
| 78 | |
| 79 | if (r) { |
| 80 | /* So far, this indicates an HTTP/1 Upgrade header initiated |
| 81 | * protocol switch. For that, the HTTP2-Settings header needs |
| 82 | * to be present and valid for the connection. |
| 83 | */ |
| 84 | const char *p; |
| 85 | |
| 86 | if (!h2_c1_can_upgrade(r)) { |
| 87 | return DECLINED; |
| 88 | } |
| 89 | |
| 90 | p = apr_table_get(r->headers_in, "HTTP2-Settings"); |
| 91 | if (!p) { |
| 92 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03085) |
| 93 | "upgrade without HTTP2-Settings declined"); |
| 94 | return DECLINED; |
| 95 | } |
| 96 | |
| 97 | p = apr_table_get(r->headers_in, "Connection"); |
| 98 | if (!ap_find_token(r->pool, p, "http2-settings")) { |
| 99 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03086) |
| 100 | "upgrade without HTTP2-Settings declined"); |
| 101 | return DECLINED; |
| 102 | } |
| 103 | |
| 104 | /* We also allow switching only for requests that have no body. |
| 105 | */ |
| 106 | p = apr_table_get(r->headers_in, "Content-Length"); |
| 107 | if ((p && strcmp(p, "0")) |
| 108 | || (!p && apr_table_get(r->headers_in, "Transfer-Encoding"))) { |
| 109 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03087) |
nothing calls this directly
no test coverage detected