| 195 | } |
| 196 | |
| 197 | static void ws_handle_resp(conn_rec *c2, h2_conn_ctx_t *conn_ctx, |
| 198 | struct ws_filter_ctx *ws_ctx, apr_bucket *b) |
| 199 | { |
| 200 | #if AP_HAS_RESPONSE_BUCKETS |
| 201 | ap_bucket_response *resp = b->data; |
| 202 | #else /* AP_HAS_RESPONSE_BUCKETS */ |
| 203 | h2_headers *resp = h2_bucket_headers_get(b); |
| 204 | #endif /* !AP_HAS_RESPONSE_BUCKETS */ |
| 205 | apr_bucket *b_override = NULL; |
| 206 | int is_final = 0; |
| 207 | int override_body = 0; |
| 208 | |
| 209 | if (ws_ctx->has_final_response) { |
| 210 | /* already did, nop */ |
| 211 | return; |
| 212 | } |
| 213 | |
| 214 | ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c2, |
| 215 | "h2_c2(%s-%d): H2_C2_WS_OUT inspecting response %d", |
| 216 | conn_ctx->id, conn_ctx->stream_id, resp->status); |
| 217 | if (resp->status == HTTP_SWITCHING_PROTOCOLS) { |
| 218 | /* The resource agreed to switch protocol. But this is only valid |
| 219 | * if it send back the correct Sec-WebSocket-Accept header value */ |
| 220 | const char *hd = apr_table_get(resp->headers, "Sec-WebSocket-Accept"); |
| 221 | if (hd && !strcmp(ws_ctx->ws_accept_base64, hd)) { |
| 222 | ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c2, |
| 223 | "h2_c2(%s-%d): websocket CONNECT, valid 101 Upgrade" |
| 224 | ", converting to 200 response", |
| 225 | conn_ctx->id, conn_ctx->stream_id); |
| 226 | b_override = make_valid_resp(c2, HTTP_OK, resp->headers, resp->notes); |
| 227 | is_final = 1; |
| 228 | } |
| 229 | else { |
| 230 | if (!hd) { |
| 231 | /* This points to someone being confused */ |
| 232 | ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c2, APLOGNO(10462) |
| 233 | "h2_c2(%s-%d): websocket CONNECT, got 101 response " |
| 234 | "without Sec-WebSocket-Accept header", |
| 235 | conn_ctx->id, conn_ctx->stream_id); |
| 236 | } |
| 237 | else { |
| 238 | /* This points to a bug, either in our WebSockets negotiation |
| 239 | * or in the request processings implementation of WebSockets */ |
| 240 | ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c2, APLOGNO(10463) |
| 241 | "h2_c2(%s-%d): websocket CONNECT, 101 response " |
| 242 | "without 'Sec-WebSocket-Accept: %s' but expected %s", |
| 243 | conn_ctx->id, conn_ctx->stream_id, hd, |
| 244 | ws_ctx->ws_accept_base64); |
| 245 | } |
| 246 | b_override = make_invalid_resp(c2, HTTP_BAD_GATEWAY, resp->notes); |
| 247 | override_body = is_final = 1; |
| 248 | } |
| 249 | } |
| 250 | else if (resp->status < 200) { |
| 251 | /* other intermediate response, pass through */ |
| 252 | } |
| 253 | else if (resp->status < 300) { |
| 254 | /* Failure, we might be talking to a plain http resource */ |
no test coverage detected