You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2022/09/27 13:21:21 UTC

svn commit: r1904305 [2/2] - in /httpd/httpd/trunk: ./ modules/http2/

Modified: httpd/httpd/trunk/modules/http2/h2_stream.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_stream.c?rev=1904305&r1=1904304&r2=1904305&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_stream.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_stream.c Tue Sep 27 13:21:21 2022
@@ -40,6 +40,7 @@
 #include "h2_mplx.h"
 #include "h2_push.h"
 #include "h2_request.h"
+#include "h2_headers.h"
 #include "h2_session.h"
 #include "h2_stream.h"
 #include "h2_c2.h"
@@ -147,7 +148,7 @@ static int on_frame(h2_stream_state_t st
 {
     ap_assert(frame_type >= 0);
     ap_assert(state >= 0);
-    if (frame_type < 0 || (apr_size_t)frame_type >= maxlen) {
+    if ((apr_size_t)frame_type >= maxlen) {
         return state; /* NOP, ignore unknown frame types */
     }
     return on_map(state, frame_map[frame_type]);
@@ -264,8 +265,14 @@ static apr_status_t close_input(h2_strea
         && !apr_is_empty_table(stream->trailers_in)) {
         ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, stream->session->c1,
                       H2_STRM_MSG(stream, "adding trailers"));
+#if AP_HAS_RESPONSE_BUCKETS
         b = ap_bucket_headers_create(stream->trailers_in,
                                      stream->pool, c->bucket_alloc);
+#else
+        b = h2_bucket_headers_create(c->bucket_alloc,
+            h2_headers_create(HTTP_OK, stream->trailers_in, NULL,
+                              stream->in_trailer_octets, stream->pool));
+#endif
         input_append_bucket(stream, b);
         stream->trailers_in = NULL;
     }
@@ -881,9 +888,15 @@ static apr_bucket *get_first_response_bu
     if (bb) {
         apr_bucket *b = APR_BRIGADE_FIRST(bb);
         while (b != APR_BRIGADE_SENTINEL(bb)) {
+#if AP_HAS_RESPONSE_BUCKETS
             if (AP_BUCKET_IS_RESPONSE(b)) {
                 return b;
             }
+#else
+            if (H2_BUCKET_IS_HEADERS(b)) {
+                return b;
+            }
+#endif
             b = APR_BUCKET_NEXT(b);
         }
     }
@@ -971,9 +984,13 @@ cleanup:
 
 static int bucket_pass_to_c1(apr_bucket *b)
 {
+#if AP_HAS_RESPONSE_BUCKETS
     return !AP_BUCKET_IS_RESPONSE(b)
            && !AP_BUCKET_IS_HEADERS(b)
            && !APR_BUCKET_IS_EOS(b);
+#else
+    return !H2_BUCKET_IS_HEADERS(b) && !APR_BUCKET_IS_EOS(b);
+#endif
 }
 
 apr_status_t h2_stream_read_to(h2_stream *stream, apr_bucket_brigade *bb, 
@@ -994,12 +1011,16 @@ apr_status_t h2_stream_read_to(h2_stream
 static apr_status_t buffer_output_process_headers(h2_stream *stream)
 {
     conn_rec *c1 = stream->session->c1;
-    ap_bucket_response *resp = NULL;
-    ap_bucket_headers *headers = NULL;
     apr_status_t rv = APR_EAGAIN;
     int ngrv = 0, is_empty;
     h2_ngheader *nh = NULL;
     apr_bucket *b, *e;
+#if AP_HAS_RESPONSE_BUCKETS
+    ap_bucket_response *resp = NULL;
+    ap_bucket_headers *headers = NULL;
+#else
+    h2_headers *headers = NULL, *resp = NULL;
+#endif
 
     if (!stream->out_buffer) goto cleanup;
 
@@ -1007,6 +1028,7 @@ static apr_status_t buffer_output_proces
     while (b != APR_BRIGADE_SENTINEL(stream->out_buffer)) {
         e = APR_BUCKET_NEXT(b);
         if (APR_BUCKET_IS_METADATA(b)) {
+#if AP_HAS_RESPONSE_BUCKETS
             if (AP_BUCKET_IS_RESPONSE(b)) {
                 resp = b->data;
                 APR_BUCKET_REMOVE(b);
@@ -1026,6 +1048,22 @@ static apr_status_t buffer_output_proces
                 b = e;
                 break;
             }
+#else /* AP_HAS_RESPONSE_BUCKETS */
+            if (H2_BUCKET_IS_HEADERS(b)) {
+                headers = h2_bucket_headers_get(b);
+                APR_BUCKET_REMOVE(b);
+                apr_bucket_destroy(b);
+                ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c1,
+                              H2_STRM_MSG(stream, "process headers, response %d"),
+                              headers->status);
+                if (!stream->response) {
+                    resp = headers;
+                    headers = NULL;
+                }
+                b = e;
+                break;
+            }
+#endif /* else AP_HAS_RESPONSE_BUCKETS */
         }
         else {
             if (!stream->response) {
@@ -1115,9 +1153,15 @@ static apr_status_t buffer_output_proces
         is_empty = 0;
         while (b != APR_BRIGADE_SENTINEL(stream->out_buffer)) {
             if (APR_BUCKET_IS_METADATA(b)) {
+#if AP_HAS_RESPONSE_BUCKETS
                 if (AP_BUCKET_IS_HEADERS(b)) {
                     break;
                 }
+#else
+                if (H2_BUCKET_IS_HEADERS(b)) {
+                    break;
+                }
+#endif
                 else if (APR_BUCKET_IS_EOS(b)) {
                     is_empty = 1;
                     break;
@@ -1184,7 +1228,11 @@ cleanup:
     return rv;
 }
 
+#if AP_HAS_RESPONSE_BUCKETS
 apr_status_t h2_stream_submit_pushes(h2_stream *stream, ap_bucket_response *response)
+#else
+apr_status_t h2_stream_submit_pushes(h2_stream *stream, h2_headers *response)
+#endif
 {
     apr_status_t status = APR_SUCCESS;
     apr_array_header_t *pushes;
@@ -1212,8 +1260,13 @@ apr_table_t *h2_stream_get_trailers(h2_s
     return NULL;
 }
 
-const h2_priority *h2_stream_get_priority(h2_stream *stream, 
+#if AP_HAS_RESPONSE_BUCKETS
+const h2_priority *h2_stream_get_priority(h2_stream *stream,
                                           ap_bucket_response *response)
+#else
+const h2_priority *h2_stream_get_priority(h2_stream *stream,
+                                          h2_headers *response)
+#endif
 {
     if (response && stream->initiated_on) {
         const char *ctype = apr_table_get(response->headers, "content-type");
@@ -1323,6 +1376,7 @@ static apr_off_t output_data_buffered(h2
                     *peos = 1;
                     break;
                 }
+#if AP_HAS_RESPONSE_BUCKETS
                 else if (AP_BUCKET_IS_RESPONSE(b)) {
                     break;
                 }
@@ -1330,6 +1384,12 @@ static apr_off_t output_data_buffered(h2
                     *pheader_blocked = 1;
                     break;
                 }
+#else
+                else if (H2_BUCKET_IS_HEADERS(b)) {
+                    *pheader_blocked = 1;
+                    break;
+                }
+#endif
             }
             else {
                 buf_len += b->length;

Modified: httpd/httpd/trunk/modules/http2/h2_stream.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_stream.h?rev=1904305&r1=1904304&r2=1904305&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_stream.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_stream.h Tue Sep 27 13:21:21 2022
@@ -20,6 +20,7 @@
 #include <http_protocol.h>
 
 #include "h2.h"
+#include "h2_headers.h"
 
 /**
  * A HTTP/2 stream, e.g. a client request+response in HTTP/1.1 terms.
@@ -28,7 +29,12 @@
  * connection to the client. The h2_session writes to the h2_stream,
  * adding HEADERS and DATA and finally an EOS. When headers are done,
  * h2_stream is scheduled for handling, which is expected to produce
- * RESPONSE buckets.
+ * h2_headers/RESPONSE buckets.
+ *
+ * The h2_headers may be followed by more h2_headers (interim responses) and
+ * by DATA frames read from the h2_stream until EOS is reached. Trailers
+ * are send when a last h2_headers is received. This always closes the stream
+ * output.
  */
 
 struct h2_mplx;
@@ -71,13 +77,17 @@ struct h2_stream {
     apr_table_t *trailers_in;   /* optional, incoming trailers */
     int request_headers_added;  /* number of request headers added */
 
+#if AP_HAS_RESPONSE_BUCKETS
     ap_bucket_response *response; /* the final, non-interim response or NULL */
+#else
+    struct h2_headers *response; /* the final, non-interim response or NULL */
+#endif
 
     struct h2_bucket_beam *input;
     apr_bucket_brigade *in_buffer;
     int in_window_size;
     apr_time_t in_last_write;
-    
+
     struct h2_bucket_beam *output;
     apr_bucket_brigade *out_buffer;
 
@@ -90,7 +100,7 @@ struct h2_stream {
     unsigned int output_eos : 1; /* output EOS in buffer/sent */
 
     conn_rec *c2;               /* connection processing stream */
-    
+
     const h2_priority *pref_priority; /* preferred priority for this stream */
     apr_off_t out_frames;       /* # of frames sent out */
     apr_off_t out_frame_octets; /* # of RAW frame octets sent out */
@@ -99,7 +109,7 @@ struct h2_stream {
     apr_off_t in_data_frames;   /* # of DATA frames received */
     apr_off_t in_data_octets;   /* # of DATA octets (payload) received */
     apr_off_t in_trailer_octets; /* # of HEADER octets (payload) received in trailers */
-    
+
     h2_stream_monitor *monitor; /* optional monitor for stream states */
 };
 
@@ -111,13 +121,13 @@ struct h2_stream {
  * @param id      the stream identifier
  * @param pool    the memory pool to use for this stream
  * @param session the session this stream belongs to
- * @param monitor an optional monitor to be called for events and 
+ * @param monitor an optional monitor to be called for events and
  *                state transisitions
  * @param initiated_on the id of the stream this one was initiated on (PUSH)
  *
  * @return the newly opened stream
  */
-h2_stream *h2_stream_create(int id, apr_pool_t *pool, 
+h2_stream *h2_stream_create(int id, apr_pool_t *pool,
                             struct h2_session *session,
                             h2_stream_monitor *monitor,
                             int initiated_on);
@@ -160,7 +170,7 @@ apr_status_t h2_stream_in_consumed(h2_st
 
 /**
  * Set complete stream headers from given h2_request.
- * 
+ *
  * @param stream stream to write request to
  * @param r the request with all the meta data
  * @param eos != 0 iff stream input is closed
@@ -169,16 +179,16 @@ void h2_stream_set_request(h2_stream *st
 
 /**
  * Set complete stream header from given request_rec.
- * 
+ *
  * @param stream stream to write request to
  * @param r the request with all the meta data
  * @param eos != 0 iff stream input is closed
  */
-apr_status_t h2_stream_set_request_rec(h2_stream *stream, 
+apr_status_t h2_stream_set_request_rec(h2_stream *stream,
                                        request_rec *r, int eos);
 
 /*
- * Add a HTTP/2 header (including pseudo headers) or trailer 
+ * Add a HTTP/2 header (including pseudo headers) or trailer
  * to the given stream, depending on stream state.
  *
  * @param stream stream to write the header to
@@ -190,7 +200,7 @@ apr_status_t h2_stream_set_request_rec(h
 apr_status_t h2_stream_add_header(h2_stream *stream,
                                   const char *name, size_t nlen,
                                   const char *value, size_t vlen);
-                                  
+
 /* End the construction of request headers */
 apr_status_t h2_stream_end_headers(h2_stream *stream, int eos, size_t raw_bytes);
 
@@ -235,7 +245,7 @@ apr_status_t h2_stream_read_output(h2_st
 
 /**
  * Read a maximum number of bytes into the bucket brigade.
- * 
+ *
  * @param stream the stream to read from
  * @param bb the brigade to append output to
  * @param plen (in-/out) max. number of bytes to append and on return actual
@@ -245,7 +255,7 @@ apr_status_t h2_stream_read_output(h2_st
  *         APR_EAGAIN if not data is available and end of stream has not been
  *         reached yet.
  */
-apr_status_t h2_stream_read_to(h2_stream *stream, apr_bucket_brigade *bb, 
+apr_status_t h2_stream_read_to(h2_stream *stream, apr_bucket_brigade *bb,
                                apr_off_t *plen, int *peos);
 
 /**
@@ -264,13 +274,24 @@ apr_table_t *h2_stream_get_trailers(h2_s
  *
  * @param stream the stream for which to submit
  */
-apr_status_t h2_stream_submit_pushes(h2_stream *stream, ap_bucket_response *response);
+#if AP_HAS_RESPONSE_BUCKETS
+apr_status_t h2_stream_submit_pushes(h2_stream *stream,
+                                     ap_bucket_response *response);
+#else
+apr_status_t h2_stream_submit_pushes(h2_stream *stream,
+                                     struct h2_headers *response);
+#endif
 
 /**
  * Get priority information set for this stream.
  */
-const struct h2_priority *h2_stream_get_priority(h2_stream *stream, 
+#if AP_HAS_RESPONSE_BUCKETS
+const struct h2_priority *h2_stream_get_priority(h2_stream *stream,
                                                  ap_bucket_response *response);
+#else
+const struct h2_priority *h2_stream_get_priority(h2_stream *stream,
+                                                 struct h2_headers *response);
+#endif
 
 /**
  * Return a textual representation of the stream state as in RFC 7540

Modified: httpd/httpd/trunk/modules/http2/h2_switch.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_switch.c?rev=1904305&r1=1904304&r2=1904305&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_switch.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_switch.c Tue Sep 27 13:21:21 2022
@@ -29,6 +29,7 @@
 #include <http_log.h>
 
 #include "h2_private.h"
+#include "h2.h"
 
 #include "h2_config.h"
 #include "h2_conn_ctx.h"
@@ -125,6 +126,7 @@ static int h2_protocol_propose(conn_rec
     return proposed? DECLINED : OK;
 }
 
+#if AP_HAS_RESPONSE_BUCKETS
 static void remove_output_filters_below(ap_filter_t *f, ap_filter_type ftype)
 {
     ap_filter_t *fnext;
@@ -146,6 +148,7 @@ static void remove_input_filters_below(a
         f = fnext;
     }
 }
+#endif
 
 static int h2_protocol_switch(conn_rec *c, request_rec *r, server_rec *s,
                               const char *protocol)
@@ -174,6 +177,7 @@ static int h2_protocol_switch(conn_rec *
 
         if (r != NULL) {
             apr_status_t status;
+#if AP_HAS_RESPONSE_BUCKETS
             /* Switching in the middle of a request means that
              * we have to send out the response to this one in h2
              * format. So we need to take over the connection
@@ -182,7 +186,15 @@ static int h2_protocol_switch(conn_rec *
              */
             remove_input_filters_below(r->input_filters, AP_FTYPE_CONNECTION);
             remove_output_filters_below(r->output_filters, AP_FTYPE_CONNECTION);
-
+#else
+            /* Switching in the middle of a request means that
+             * we have to send out the response to this one in h2
+             * format. So we need to take over the connection
+             * right away.
+             */
+            ap_remove_input_filter_byhandle(r->input_filters, "http_in");
+            ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER");
+#endif
             /* Ok, start an h2_conn on this one. */
             status = h2_c1_setup(c, r, s);
             

Modified: httpd/httpd/trunk/modules/http2/h2_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_util.c?rev=1904305&r1=1904304&r2=1904305&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_util.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_util.c Tue Sep 27 13:21:21 2022
@@ -28,6 +28,7 @@
 #include <nghttp2/nghttp2.h>
 
 #include "h2.h"
+#include "h2_headers.h"
 #include "h2_util.h"
 
 /* h2_log2(n) iff n is a power of 2 */
@@ -1172,7 +1173,7 @@ apr_size_t h2_util_table_bytes(apr_table
 static void fit_bucket_into(apr_bucket *b, apr_off_t *plen)
 {
     /* signed apr_off_t is at least as large as unsigned apr_size_t.
-     * Propblems may arise when they are both the same size. Then
+     * Problems may arise when they are both the same size. Then
      * the bucket length *may* be larger than a value we can hold
      * in apr_off_t. Before casting b->length to apr_off_t we must
      * check the limitations.
@@ -1502,6 +1503,8 @@ static apr_status_t ngheader_create(h2_n
     return ctx.status;
 }
 
+#if AP_HAS_RESPONSE_BUCKETS
+
 static int is_unsafe(ap_bucket_response *h)
 {
     const char *v = h->notes? apr_table_get(h->notes, H2_HDR_CONFORMANCE) : NULL;
@@ -1528,6 +1531,36 @@ apr_status_t h2_res_create_ngheader(h2_n
                            H2_ALEN(keys), keys, values, response->headers);
 }
 
+#else /* AP_HAS_RESPONSE_BUCKETS */
+
+static int is_unsafe(h2_headers *h)
+{
+    const char *v = h->notes? apr_table_get(h->notes, H2_HDR_CONFORMANCE) : NULL;
+    return (v && !strcmp(v, H2_HDR_CONFORMANCE_UNSAFE));
+}
+
+apr_status_t h2_res_create_ngtrailer(h2_ngheader **ph, apr_pool_t *p,
+                                    h2_headers *headers)
+{
+    return ngheader_create(ph, p, is_unsafe(headers),
+                           0, NULL, NULL, headers->headers);
+}
+
+apr_status_t h2_res_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
+                                    h2_headers *headers)
+{
+    const char *keys[] = {
+        ":status"
+    };
+    const char *values[] = {
+        apr_psprintf(p, "%d", headers->status)
+    };
+    return ngheader_create(ph, p, is_unsafe(headers),
+                           H2_ALEN(keys), keys, values, headers->headers);
+}
+
+#endif /* else AP_HAS_RESPONSE_BUCKETS */
+
 apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
                                     const struct h2_request *req)
 {
@@ -1825,6 +1858,8 @@ apr_status_t h2_util_wait_on_pipe(apr_fi
     return apr_file_read(pipe, rb, &nr);
 }
 
+#if AP_HAS_RESPONSE_BUCKETS
+
 static int add_header_lengths(void *ctx, const char *name, const char *value)
 {
     apr_size_t *plen = ctx;
@@ -1844,4 +1879,6 @@ apr_size_t response_length_estimate(ap_b
     apr_size_t len = 3 + 1 + 8 + (resp->reason? strlen(resp->reason) : 10);
     apr_table_do(add_header_lengths, &len, resp->headers, NULL);
     return len;
-}
\ No newline at end of file
+}
+
+#endif /* AP_HAS_RESPONSE_BUCKETS */
\ No newline at end of file

Modified: httpd/httpd/trunk/modules/http2/h2_util.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_util.h?rev=1904305&r1=1904304&r2=1904305&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_util.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_util.h Tue Sep 27 13:21:21 2022
@@ -18,6 +18,10 @@
 #define __mod_h2__h2_util__
 
 #include <nghttp2/nghttp2.h>
+#include <http_protocol.h>
+
+#include "h2.h"
+#include "h2_headers.h"
 
 /*******************************************************************************
  * some debugging/format helpers
@@ -396,12 +400,21 @@ typedef struct h2_ngheader {
     apr_size_t nvlen;
 } h2_ngheader;
 
-apr_status_t h2_res_create_ngtrailer(h2_ngheader **ph, apr_pool_t *p, 
+#if AP_HAS_RESPONSE_BUCKETS
+apr_status_t h2_res_create_ngtrailer(h2_ngheader **ph, apr_pool_t *p,
                                      ap_bucket_headers *headers);
 apr_status_t h2_res_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
                                     ap_bucket_response *response);
-apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p, 
+apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
+                                    const struct h2_request *req);
+#else
+apr_status_t h2_res_create_ngtrailer(h2_ngheader **ph, apr_pool_t *p,
+                                     struct h2_headers *headers);
+apr_status_t h2_res_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
+                                    struct h2_headers *headers);
+apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
                                     const struct h2_request *req);
+#endif
 
 /**
  * Add a HTTP/2 header and return the table key if it really was added
@@ -507,6 +520,8 @@ void h2_util_drain_pipe(apr_file_t *pipe
  */
 apr_status_t h2_util_wait_on_pipe(apr_file_t *pipe);
 
+
+#if AP_HAS_RESPONSE_BUCKETS
 /**
  * Give an estimate of the length of the header fields,
  * without compression or other formatting decorations.
@@ -518,5 +533,6 @@ apr_size_t headers_length_estimate(ap_bu
  * without compression or other formatting decorations.
  */
 apr_size_t response_length_estimate(ap_bucket_response *resp);
+#endif /* AP_HAS_RESPONSE_BUCKETS */
 
 #endif /* defined(__mod_h2__h2_util__) */

Modified: httpd/httpd/trunk/modules/http2/h2_version.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_version.h?rev=1904305&r1=1904304&r2=1904305&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_version.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_version.h Tue Sep 27 13:21:21 2022
@@ -27,7 +27,7 @@
  * @macro
  * Version number of the http2 module as c string
  */
-#define MOD_HTTP2_VERSION "2.0.7"
+#define MOD_HTTP2_VERSION "2.0.8-dev"
 
 /**
  * @macro
@@ -35,7 +35,7 @@
  * release. This is a 24 bit number with 8 bits for major number, 8 bits
  * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
  */
-#define MOD_HTTP2_VERSION_NUM 0x020007
+#define MOD_HTTP2_VERSION_NUM 0x020008
 
 
 #endif /* mod_h2_h2_version_h */

Modified: httpd/httpd/trunk/modules/http2/h2_workers.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_workers.c?rev=1904305&r1=1904304&r2=1904305&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_workers.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_workers.c Tue Sep 27 13:21:21 2022
@@ -288,7 +288,11 @@ static void* APR_THREAD_FUNC slot_run(ap
                 c->current_thread = thread;
                 AP_DEBUG_ASSERT(slot->prod);
 
+#if AP_HAS_RESPONSE_BUCKETS
                 ap_process_connection(c, ap_get_conn_socket(c));
+#else
+                h2_c2_process(c, thread, slot->id);
+#endif
                 slot->prod->fn_done(slot->prod->baton, c);
 
                 apr_thread_mutex_lock(workers->lock);

Modified: httpd/httpd/trunk/modules/http2/mod_http2.dsp
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/mod_http2.dsp?rev=1904305&r1=1904304&r2=1904305&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/mod_http2.dsp (original)
+++ httpd/httpd/trunk/modules/http2/mod_http2.dsp Tue Sep 27 13:21:21 2022
@@ -133,6 +133,10 @@ SOURCE=./h2_conn_ctx.c
 # End Source File
 # Begin Source File
 
+SOURCE=./h2_headers.c
+# End Source File
+# Begin Source File
+
 SOURCE=./h2_mplx.c
 # End Source File
 # Begin Source File