]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
HTTP/2, websockets
authorStefan Eissing <icing@apache.org>
Mon, 14 Aug 2023 14:39:00 +0000 (14:39 +0000)
committerStefan Eissing <icing@apache.org>
Mon, 14 Aug 2023 14:39:00 +0000 (14:39 +0000)
- provide "Connection" header in internal Upgrade request
- set input notification if input is already available when
  stream processing is started
- add optional function in mod_http2.h to use instead of
  ap_get_pollfd_from_conn() in older servers with a new
  mod_http2

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1911650 13f79535-47bb-0310-9956-ffa450edef68

modules/http2/h2_c2.c
modules/http2/h2_c2_filter.c
modules/http2/h2_mplx.c
modules/http2/h2_ws.c
modules/http2/mod_http2.h

index 9ca888f9e4c700e505cb6530d2b13ed09257e4fb..316b0cc46370dde1494c4f931fdeabc3472e4fd0 100644 (file)
@@ -51,6 +51,7 @@
 #include "h2_ws.h"
 #include "h2_c2.h"
 #include "h2_util.h"
+#include "mod_http2.h"
 
 
 static module *mpm_module;
@@ -469,10 +470,9 @@ static int c2_hook_fixups(request_rec *r)
     return DECLINED;
 }
 
-#if H2_USE_POLLFD_FROM_CONN
-static apr_status_t c2_get_pollfd_from_conn(conn_rec *c,
-                                            struct apr_pollfd_t *pfd,
-                                            apr_interval_time_t *ptimeout)
+static apr_status_t http2_get_pollfd_from_conn(conn_rec *c,
+                                               struct apr_pollfd_t *pfd,
+                                               apr_interval_time_t *ptimeout)
 {
     if (c->master) {
         h2_conn_ctx_t *ctx = h2_conn_ctx_get(c);
@@ -494,7 +494,6 @@ static apr_status_t c2_get_pollfd_from_conn(conn_rec *c,
     }
     return APR_ENOTIMPL;
 }
-#endif
 
 #if AP_HAS_RESPONSE_BUCKETS
 
@@ -601,9 +600,10 @@ void h2_c2_register_hooks(void)
                               APR_HOOK_REALLY_FIRST);
     ap_hook_fixups(c2_hook_fixups, NULL, NULL, APR_HOOK_LAST);
 #if H2_USE_POLLFD_FROM_CONN
-    ap_hook_get_pollfd_from_conn(c2_get_pollfd_from_conn, NULL, NULL,
+    ap_hook_get_pollfd_from_conn(http2_get_pollfd_from_conn, NULL, NULL,
                                  APR_HOOK_MIDDLE);
 #endif
+    APR_REGISTER_OPTIONAL_FN(http2_get_pollfd_from_conn);
 
     c2_net_in_filter_handle =
         ap_register_input_filter("H2_C2_NET_IN", h2_c2_filter_in,
@@ -913,9 +913,10 @@ void h2_c2_register_hooks(void)
     ap_hook_post_read_request(h2_c2_hook_post_read_request, NULL, NULL, APR_HOOK_REALLY_FIRST);
     ap_hook_fixups(c2_hook_fixups, NULL, NULL, APR_HOOK_LAST);
 #if H2_USE_POLLFD_FROM_CONN
-    ap_hook_get_pollfd_from_conn(c2_get_pollfd_from_conn, NULL, NULL,
+    ap_hook_get_pollfd_from_conn(http2_get_pollfd_from_conn, NULL, NULL,
                                  APR_HOOK_MIDDLE);
 #endif
+    APR_REGISTER_OPTIONAL_FN(http2_get_pollfd_from_conn);
 
     ap_register_input_filter("H2_C2_NET_IN", h2_c2_filter_in,
                              NULL, AP_FTYPE_NETWORK);
index 97c38b3f6dc002083f386f43e5c2cbea518ab698..523a941450b88f6286f806a3ac551daf0b035eb5 100644 (file)
@@ -914,10 +914,10 @@ static apr_status_t read_and_chunk(ap_filter_t *f, h2_conn_ctx_t *conn_ctx,
 }
 
 apr_status_t h2_c2_filter_request_in(ap_filter_t* f,
-                                  apr_bucket_brigade* bb,
-                                  ap_input_mode_t mode,
-                                  apr_read_type_e block,
-                                  apr_off_t readbytes)
+                                     apr_bucket_brigade* bb,
+                                     ap_input_mode_t mode,
+                                     apr_read_type_e block,
+                                     apr_off_t readbytes)
 {
     h2_conn_ctx_t *conn_ctx = h2_conn_ctx_get(f->c);
     h2_chunk_filter_t *fctx = f->ctx;
index 2cfb44478c71f68e4558e8d7940d374cf3ed2a4f..460a38a00a95f011f4baf69fc916dc9ce2155c96 100644 (file)
@@ -828,6 +828,8 @@ static apr_status_t c2_setup_io(h2_mplx *m, conn_rec *c2, h2_stream *stream, h2_
         if (APR_SUCCESS != rv) goto cleanup;
 #endif
         h2_beam_on_eagain(stream->input, c2_beam_input_read_eagain, c2);
+        if (!h2_beam_empty(stream->input))
+            c2_beam_input_write_notify(c2, stream->input);
     }
 
 cleanup:
index d2a51af6b7b18d454e3cbdd01e0651aaa0993c30..51f80a8ee144b473eb2294e35dfbabc40ccd5350 100644 (file)
@@ -113,6 +113,7 @@ const h2_request *h2_ws_rewrite_request(const h2_request *req,
     wsreq->method = "GET";
     wsreq->protocol = NULL;
     apr_table_set(wsreq->headers, "Upgrade", "websocket");
+    apr_table_add(wsreq->headers, "Connection", "Upgrade");
     /* add Sec-WebSocket-Key header */
     rv = apr_generate_random_bytes(key_raw, sizeof(key_raw));
     if (rv != APR_SUCCESS) {
index f68edcdb5b19cf7137df685bfb23082e39c5a82f..78cf94c8aa318848c40dbf42092c4910c6da4a86 100644 (file)
@@ -32,6 +32,15 @@ APR_DECLARE_OPTIONAL_FN(void,
                         http2_get_num_workers, (server_rec *s,
                                                 int *minw, int *max));
 
+#define AP_HTTP2_HAS_GET_POLLFD
+
+/* Get a apr_pollfd_t propulated for a h2 connection where
+ * (c->master != NULL) is true. */
+APR_DECLARE_OPTIONAL_FN(apr_status_t,
+                        http2_get_pollfd_from_conn,
+                        (conn_rec *c, struct apr_pollfd_t *pfd,
+                         apr_interval_time_t *ptimeout));
+
 /*******************************************************************************
  * START HTTP/2 request engines (DEPRECATED)
  ******************************************************************************/