| 1074 | } |
| 1075 | |
| 1076 | static apr_status_t h2_session_start(h2_session *session, int *rv) |
| 1077 | { |
| 1078 | apr_status_t status = APR_SUCCESS; |
| 1079 | nghttp2_settings_entry settings[4]; |
| 1080 | size_t slen; |
| 1081 | int win_size; |
| 1082 | |
| 1083 | ap_assert(session); |
| 1084 | /* Start the conversation by submitting our SETTINGS frame */ |
| 1085 | *rv = 0; |
| 1086 | if (session->r) { |
| 1087 | const char *s, *cs; |
| 1088 | apr_size_t dlen; |
| 1089 | h2_stream * stream; |
| 1090 | |
| 1091 | /* 'h2c' mode: we should have a 'HTTP2-Settings' header with |
| 1092 | * base64 encoded client settings. */ |
| 1093 | s = apr_table_get(session->r->headers_in, "HTTP2-Settings"); |
| 1094 | if (!s) { |
| 1095 | ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_EINVAL, session->r, |
| 1096 | APLOGNO(02931) |
| 1097 | "HTTP2-Settings header missing in request"); |
| 1098 | return APR_EINVAL; |
| 1099 | } |
| 1100 | cs = NULL; |
| 1101 | dlen = h2_util_base64url_decode(&cs, s, session->pool); |
| 1102 | |
| 1103 | if (APLOGrdebug(session->r)) { |
| 1104 | char buffer[128]; |
| 1105 | h2_util_hex_dump(buffer, 128, (char*)cs, dlen); |
| 1106 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, session->r, APLOGNO(03070) |
| 1107 | "upgrading h2c session with HTTP2-Settings: %s -> %s (%d)", |
| 1108 | s, buffer, (int)dlen); |
| 1109 | } |
| 1110 | |
| 1111 | *rv = nghttp2_session_upgrade(session->ngh2, (uint8_t*)cs, dlen, NULL); |
| 1112 | if (*rv != 0) { |
| 1113 | status = APR_EINVAL; |
| 1114 | ap_log_rerror(APLOG_MARK, APLOG_ERR, status, session->r, |
| 1115 | APLOGNO(02932) "nghttp2_session_upgrade: %s", |
| 1116 | nghttp2_strerror(*rv)); |
| 1117 | return status; |
| 1118 | } |
| 1119 | |
| 1120 | /* Now we need to auto-open stream 1 for the request we got. */ |
| 1121 | stream = h2_session_open_stream(session, 1, 0); |
| 1122 | if (!stream) { |
| 1123 | status = APR_EGENERAL; |
| 1124 | ap_log_rerror(APLOG_MARK, APLOG_ERR, status, session->r, |
| 1125 | APLOGNO(02933) "open stream 1: %s", |
| 1126 | nghttp2_strerror(*rv)); |
| 1127 | return status; |
| 1128 | } |
| 1129 | |
| 1130 | status = h2_stream_set_request_rec(stream, session->r, 1); |
| 1131 | if (status != APR_SUCCESS) { |
| 1132 | return status; |
| 1133 | } |
no test coverage detected