| 1142 | ******************************************************************************/ |
| 1143 | |
| 1144 | static int reset_is_acceptable(h2_stream *stream) |
| 1145 | { |
| 1146 | /* client may terminate a stream via H2 RST_STREAM message at any time. |
| 1147 | * This is annyoing when we have committed resources (e.g. worker threads) |
| 1148 | * to it, so our mood (e.g. willingness to commit resources on this |
| 1149 | * connection in the future) goes down. |
| 1150 | * |
| 1151 | * This is a DoS protection. We do not want to make it too easy for |
| 1152 | * a client to eat up server resources. |
| 1153 | * |
| 1154 | * However: there are cases where a RST_STREAM is the only way to end |
| 1155 | * a request. This includes websockets and server-side-event streams (SSEs). |
| 1156 | * The responses to such requests continue forever otherwise. |
| 1157 | * |
| 1158 | */ |
| 1159 | if (stream->rst_error) return 0; /* errored stream. bad. */ |
| 1160 | if (!stream_is_running(stream)) return 1; |
| 1161 | if (!(stream->id & 0x01)) return 1; /* stream initiated by us. acceptable. */ |
| 1162 | if (!stream->response) return 0; /* no response headers produced yet. bad. */ |
| 1163 | if (!stream->out_data_frames) return 0; /* no response body data sent yet. bad. */ |
| 1164 | return 1; /* otherwise, be forgiving */ |
| 1165 | } |
| 1166 | |
| 1167 | apr_status_t h2_mplx_c1_client_rst(h2_mplx *m, int stream_id, h2_stream *stream) |
| 1168 | { |
no test coverage detected