Compare commits

...

No commits in common. "c8" and "c10s" have entirely different histories.
c8 ... c10s

11 changed files with 666 additions and 2095 deletions

4
.gitignore vendored
View File

@ -1 +1,3 @@
SOURCES/nghttp2-1.33.0.tar.xz
/nghttp2-[0-9]*
/nghttp2-[0-9]*.tar.xz
/nghttp2-[0-9]*.tar.xz.asc

View File

@ -1 +0,0 @@
0a11f7de6ea8e66fbecc9fe4ddc61b6ab40af469 SOURCES/nghttp2-1.33.0.tar.xz

25
.packit.yml Normal file
View File

@ -0,0 +1,25 @@
# docs: https://packit.dev/docs/category/downstream-jobs
---
specfile_path: nghttp2.spec
upstream_project_url: https://github.com/nghttp2/nghttp2
upstream_tag_template: "v{version}"
actions:
changelog-entry:
- echo "- update to the latest upstream release"
jobs:
- job: pull_from_upstream
trigger: release
dist_git_branches:
- fedora-rawhide
issue_repository: https://src.fedoraproject.org/rpms/nghttp2
- job: koji_build
trigger: commit
allowed_pr_authors: [ packit ]
allowed_committers: [ jamacku, msekleta, kdudka ]
dist_git_branches:
- fedora-rawhide

View File

@ -1,976 +0,0 @@
From 095040ff7ac242cec5075b8d4bd8c9884bc3ec30 Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Sun, 1 Oct 2023 00:05:01 +0900
Subject: [PATCH] Rework session management
(cherry picked from commit 72b4af6143681f528f1d237b21a9a7aee1738832)
Signed-off-by: Jan Macku <jamacku@redhat.com>
---
CMakeLists.txt | 4 ++
cmakeconfig.h.in | 9 +++
configure.ac | 21 +++++++
doc/Makefile.am | 1 +
lib/CMakeLists.txt | 2 +
lib/Makefile.am | 4 ++
lib/includes/nghttp2/nghttp2.h | 17 ++++++
lib/nghttp2_option.c | 7 +++
lib/nghttp2_option.h | 6 ++
lib/nghttp2_ratelim.c | 75 ++++++++++++++++++++++++
lib/nghttp2_ratelim.h | 57 ++++++++++++++++++
lib/nghttp2_session.c | 34 ++++++++++-
lib/nghttp2_session.h | 12 +++-
lib/nghttp2_time.c | 62 ++++++++++++++++++++
lib/nghttp2_time.h | 38 ++++++++++++
tests/CMakeLists.txt | 1 +
tests/Makefile.am | 6 +-
tests/main.c | 7 ++-
tests/nghttp2_ratelim_test.c | 101 ++++++++++++++++++++++++++++++++
tests/nghttp2_ratelim_test.h | 35 +++++++++++
tests/nghttp2_session_test.c | 103 +++++++++++++++++++++++++++++++++
tests/nghttp2_session_test.h | 1 +
22 files changed, 598 insertions(+), 5 deletions(-)
create mode 100644 lib/nghttp2_ratelim.c
create mode 100644 lib/nghttp2_ratelim.h
create mode 100644 lib/nghttp2_time.c
create mode 100644 lib/nghttp2_time.h
create mode 100644 tests/nghttp2_ratelim_test.c
create mode 100644 tests/nghttp2_ratelim_test.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dbac6c8..78b356d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -262,6 +262,7 @@ check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
check_include_file("pwd.h" HAVE_PWD_H)
check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H)
check_include_file("sys/time.h" HAVE_SYS_TIME_H)
+check_include_file("sysinfoapi.h" HAVE_SYSINFOAPI_H)
check_include_file("syslog.h" HAVE_SYSLOG_H)
check_include_file("time.h" HAVE_TIME_H)
check_include_file("unistd.h" HAVE_UNISTD_H)
@@ -302,8 +303,11 @@ check_type_size("time_t" SIZEOF_TIME_T)
include(CheckFunctionExists)
check_function_exists(_Exit HAVE__EXIT)
check_function_exists(accept4 HAVE_ACCEPT4)
+check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
check_function_exists(mkostemp HAVE_MKOSTEMP)
+check_symbol_exists(GetTickCount64 sysinfoapi.h HAVE_GETTICKCOUNT64)
+
include(CheckSymbolExists)
# XXX does this correctly detect initgroups (un)availability on cygwin?
check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS)
diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in
index d67b540..4065029 100644
--- a/cmakeconfig.h.in
+++ b/cmakeconfig.h.in
@@ -34,9 +34,15 @@
/* Define to 1 if you have the `accept4` function. */
#cmakedefine HAVE_ACCEPT4 1
+/* Define to 1 if you have the `clock_gettime` function. */
+#cmakedefine HAVE_CLOCK_GETTIME 1
+
/* Define to 1 if you have the `mkostemp` function. */
#cmakedefine HAVE_MKOSTEMP 1
+/* Define to 1 if you have the `GetTickCount64` function. */
+#cmakedefine HAVE_GETTICKCOUNT64 1
+
/* Define to 1 if you have the `initgroups` function. */
#cmakedefine01 HAVE_DECL_INITGROUPS
@@ -73,6 +79,9 @@
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H 1
+/* Define to 1 if you have the <sysinfoapi.h> header file. */
+#cmakedefine HAVE_SYSINFOAPI_H 1
+
/* Define to 1 if you have the <syslog.h> header file. */
#cmakedefine HAVE_SYSLOG_H 1
diff --git a/configure.ac b/configure.ac
index a54398e..a41492c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -607,6 +607,7 @@ AC_CHECK_HEADERS([ \
string.h \
sys/socket.h \
sys/time.h \
+ sysinfoapi.h \
syslog.h \
time.h \
unistd.h \
@@ -681,6 +682,7 @@ AC_FUNC_STRNLEN
AC_CHECK_FUNCS([ \
_Exit \
accept4 \
+ clock_gettime \
dup2 \
getcwd \
getpwnam \
@@ -706,6 +708,25 @@ AC_CHECK_FUNCS([ \
AC_CHECK_FUNC([timerfd_create],
[have_timerfd_create=yes], [have_timerfd_create=no])
+AC_MSG_CHECKING([checking for GetTickCount64])
+AC_LINK_IFELSE([AC_LANG_PROGRAM(
+[[
+#include <sysinfoapi.h>
+]],
+[[
+GetTickCount64();
+]])],
+[have_gettickcount64=yes],
+[have_gettickcount64=no])
+
+if test "x${have_gettickcount64}" = "xyes"; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_GETTICKCOUNT64], [1],
+ [Define to 1 if you have `GetTickCount64` function.])
+else
+ AC_MSG_RESULT([no])
+fi
+
# For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but
# cygwin disables initgroups due to feature test macro magic with our
# configuration. FreeBSD declares initgroups() in unistd.h.
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 5a58f8e..87f6c43 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -69,6 +69,7 @@ APIDOCS= \
nghttp2_option_set_user_recv_extension_type.rst \
nghttp2_option_set_max_outbound_ack.rst \
nghttp2_option_set_max_settings.rst \
+ nghttp2_option_set_stream_reset_rate_limit.rst \
nghttp2_pack_settings_payload.rst \
nghttp2_priority_spec_check_default.rst \
nghttp2_priority_spec_default_init.rst \
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 17e422b..d44de28 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -23,6 +23,8 @@ set(NGHTTP2_SOURCES
nghttp2_mem.c
nghttp2_http.c
nghttp2_rcbuf.c
+ nghttp2_ratelim.c
+ nghttp2_time.c
nghttp2_debug.c
)
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 24a5bd6..595714d 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -49,6 +49,8 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_mem.c \
nghttp2_http.c \
nghttp2_rcbuf.c \
+ nghttp2_ratelim.c \
+ nghttp2_time.c \
nghttp2_debug.c
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
@@ -65,6 +67,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_mem.h \
nghttp2_http.h \
nghttp2_rcbuf.h \
+ nghttp2_ratelim.h \
+ nghttp2_time.h \
nghttp2_debug.h
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h
index b0ff6c5..9eb764c 100644
--- a/lib/includes/nghttp2/nghttp2.h
+++ b/lib/includes/nghttp2/nghttp2.h
@@ -2671,6 +2671,23 @@ NGHTTP2_EXTERN void nghttp2_option_set_max_outbound_ack(nghttp2_option *option,
NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option,
size_t val);
+/**
+ * @function
+ *
+ * This function sets the rate limit for the incoming stream reset
+ * (RST_STREAM frame). It is server use only. It is a token-bucket
+ * based rate limiter. |burst| specifies the number of tokens that is
+ * initially available. The maximum number of tokens is capped to
+ * this value. |rate| specifies the number of tokens that are
+ * regenerated per second. An incoming RST_STREAM consumes one token.
+ * If there is no token available, GOAWAY is sent to tear down the
+ * connection. |burst| and |rate| default to 1000 and 33
+ * respectively.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
+ uint64_t burst, uint64_t rate);
+
/**
* @function
*
diff --git a/lib/nghttp2_option.c b/lib/nghttp2_option.c
index 34348e6..0d9a404 100644
--- a/lib/nghttp2_option.c
+++ b/lib/nghttp2_option.c
@@ -126,3 +126,10 @@ void nghttp2_option_set_max_settings(nghttp2_option *option, size_t val) {
option->opt_set_mask |= NGHTTP2_OPT_MAX_SETTINGS;
option->max_settings = val;
}
+
+void nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
+ uint64_t burst, uint64_t rate) {
+ option->opt_set_mask |= NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT;
+ option->stream_reset_burst = burst;
+ option->stream_reset_rate = rate;
+}
diff --git a/lib/nghttp2_option.h b/lib/nghttp2_option.h
index 939729f..e6ba910 100644
--- a/lib/nghttp2_option.h
+++ b/lib/nghttp2_option.h
@@ -68,12 +68,18 @@ typedef enum {
NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10,
NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11,
NGHTTP2_OPT_MAX_SETTINGS = 1 << 12,
+ NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15,
} nghttp2_option_flag;
/**
* Struct to store option values for nghttp2_session.
*/
struct nghttp2_option {
+ /**
+ * NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT
+ */
+ uint64_t stream_reset_burst;
+ uint64_t stream_reset_rate;
/**
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
*/
diff --git a/lib/nghttp2_ratelim.c b/lib/nghttp2_ratelim.c
new file mode 100644
index 0000000..7011655
--- /dev/null
+++ b/lib/nghttp2_ratelim.c
@@ -0,0 +1,75 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_ratelim.h"
+#include "nghttp2_helper.h"
+
+void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate) {
+ rl->val = rl->burst = burst;
+ rl->rate = rate;
+ rl->tstamp = 0;
+}
+
+void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp) {
+ uint64_t d, gain;
+
+ if (tstamp == rl->tstamp) {
+ return;
+ }
+
+ if (tstamp > rl->tstamp) {
+ d = tstamp - rl->tstamp;
+ } else {
+ d = 1;
+ }
+
+ rl->tstamp = tstamp;
+
+ if (UINT64_MAX / d < rl->rate) {
+ rl->val = rl->burst;
+
+ return;
+ }
+
+ gain = rl->rate * d;
+
+ if (UINT64_MAX - gain < rl->val) {
+ rl->val = rl->burst;
+
+ return;
+ }
+
+ rl->val += gain;
+ rl->val = nghttp2_min(rl->val, rl->burst);
+}
+
+int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n) {
+ if (rl->val < n) {
+ return -1;
+ }
+
+ rl->val -= n;
+
+ return 0;
+}
diff --git a/lib/nghttp2_ratelim.h b/lib/nghttp2_ratelim.h
new file mode 100644
index 0000000..866ed3f
--- /dev/null
+++ b/lib/nghttp2_ratelim.h
@@ -0,0 +1,57 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_RATELIM_H
+#define NGHTTP2_RATELIM_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+typedef struct nghttp2_ratelim {
+ /* burst is the maximum value of val. */
+ uint64_t burst;
+ /* rate is the amount of value that is regenerated per 1 tstamp. */
+ uint64_t rate;
+ /* val is the amount of value available to drain. */
+ uint64_t val;
+ /* tstamp is the last timestamp in second resolution that is known
+ to this object. */
+ uint64_t tstamp;
+} nghttp2_ratelim;
+
+/* nghttp2_ratelim_init initializes |rl| with the given parameters. */
+void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate);
+
+/* nghttp2_ratelim_update updates rl->val with the current |tstamp|
+ given in second resolution. */
+void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp);
+
+/* nghttp2_ratelim_drain drains |n| from rl->val. It returns 0 if it
+ succeeds, or -1. */
+int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n);
+
+#endif /* NGHTTP2_RATELIM_H */
diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c
index 8271198..5ee08df 100644
--- a/lib/nghttp2_session.c
+++ b/lib/nghttp2_session.c
@@ -36,6 +36,7 @@
#include "nghttp2_option.h"
#include "nghttp2_http.h"
#include "nghttp2_pq.h"
+#include "nghttp2_time.h"
#include "nghttp2_debug.h"
/*
@@ -443,6 +444,10 @@ static int session_new(nghttp2_session **session_ptr,
NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
(*session_ptr)->pending_enable_push = 1;
+ nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim,
+ NGHTTP2_DEFAULT_STREAM_RESET_BURST,
+ NGHTTP2_DEFAULT_STREAM_RESET_RATE);
+
if (server) {
(*session_ptr)->server = 1;
}
@@ -527,6 +532,12 @@ static int session_new(nghttp2_session **session_ptr,
option->max_settings) {
(*session_ptr)->max_settings = option->max_settings;
}
+
+ if (option->opt_set_mask & NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT) {
+ nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim,
+ option->stream_reset_burst,
+ option->stream_reset_rate);
+ }
}
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
@@ -4144,6 +4155,23 @@ static int session_process_priority_frame(nghttp2_session *session) {
return nghttp2_session_on_priority_received(session, frame);
}
+static int session_update_stream_reset_ratelim(nghttp2_session *session) {
+ if (!session->server || (session->goaway_flags & NGHTTP2_GOAWAY_SUBMITTED)) {
+ return 0;
+ }
+
+ nghttp2_ratelim_update(&session->stream_reset_ratelim,
+ nghttp2_time_now_sec());
+
+ if (nghttp2_ratelim_drain(&session->stream_reset_ratelim, 1) == 0) {
+ return 0;
+ }
+
+ return nghttp2_session_add_goaway(session, session->last_recv_stream_id,
+ NGHTTP2_INTERNAL_ERROR, NULL, 0,
+ NGHTTP2_GOAWAY_AUX_NONE);
+}
+
int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
nghttp2_frame *frame) {
int rv;
@@ -4173,7 +4201,8 @@ int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
if (nghttp2_is_fatal(rv)) {
return rv;
}
- return 0;
+
+ return session_update_stream_reset_ratelim(session);
}
static int session_process_rst_stream_frame(nghttp2_session *session) {
@@ -6941,6 +6970,9 @@ int nghttp2_session_add_goaway(nghttp2_session *session, int32_t last_stream_id,
nghttp2_mem_free(mem, item);
return rv;
}
+
+ session->goaway_flags |= NGHTTP2_GOAWAY_SUBMITTED;
+
return 0;
}
diff --git a/lib/nghttp2_session.h b/lib/nghttp2_session.h
index e62a3bb..03f8bee 100644
--- a/lib/nghttp2_session.h
+++ b/lib/nghttp2_session.h
@@ -39,6 +39,7 @@
#include "nghttp2_buf.h"
#include "nghttp2_callbacks.h"
#include "nghttp2_mem.h"
+#include "nghttp2_ratelim.h"
/* The global variable for tests where we want to disable strict
preface handling. */
@@ -102,6 +103,10 @@ typedef struct {
/* The default value of maximum number of concurrent streams. */
#define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
+/* The default values for stream reset rate limiter. */
+#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
+#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
+
/* Internal state when receiving incoming frame */
typedef enum {
/* Receiving frame header */
@@ -175,7 +180,9 @@ typedef enum {
/* Flag means GOAWAY was sent */
NGHTTP2_GOAWAY_SENT = 0x4,
/* Flag means GOAWAY was received */
- NGHTTP2_GOAWAY_RECV = 0x8
+ NGHTTP2_GOAWAY_RECV = 0x8,
+ /* Flag means GOAWAY has been submitted at least once */
+ NGHTTP2_GOAWAY_SUBMITTED = 0x10
} nghttp2_goaway_flag;
/* nghttp2_inflight_settings stores the SETTINGS entries which local
@@ -229,6 +236,9 @@ struct nghttp2_session {
/* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not
considered as in-flight. */
nghttp2_inflight_settings *inflight_settings_head;
+ /* Stream reset rate limiter. If receiving excessive amount of
+ stream resets, GOAWAY will be sent. */
+ nghttp2_ratelim stream_reset_ratelim;
/* The number of outgoing streams. This will be capped by
remote_settings.max_concurrent_streams. */
size_t num_outgoing_streams;
diff --git a/lib/nghttp2_time.c b/lib/nghttp2_time.c
new file mode 100644
index 0000000..2a5f1a6
--- /dev/null
+++ b/lib/nghttp2_time.c
@@ -0,0 +1,62 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_time.h"
+
+#ifdef HAVE_TIME_H
+# include <time.h>
+#endif /* HAVE_TIME_H */
+
+#ifdef HAVE_SYSINFOAPI_H
+# include <sysinfoapi.h>
+#endif /* HAVE_SYSINFOAPI_H */
+
+#ifndef HAVE_GETTICKCOUNT64
+static uint64_t time_now_sec(void) {
+ time_t t = time(NULL);
+
+ if (t == -1) {
+ return 0;
+ }
+
+ return (uint64_t)t;
+}
+#endif /* HAVE_GETTICKCOUNT64 */
+
+#ifdef HAVE_CLOCK_GETTIME
+uint64_t nghttp2_time_now_sec(void) {
+ struct timespec tp;
+ int rv = clock_gettime(CLOCK_MONOTONIC, &tp);
+
+ if (rv == -1) {
+ return time_now_sec();
+ }
+
+ return (uint64_t)tp.tv_sec;
+}
+#elif defined(HAVE_GETTICKCOUNT64)
+uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; }
+#else /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */
+uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); }
+#endif /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */
diff --git a/lib/nghttp2_time.h b/lib/nghttp2_time.h
new file mode 100644
index 0000000..03c0bbe
--- /dev/null
+++ b/lib/nghttp2_time.h
@@ -0,0 +1,38 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_TIME_H
+#define NGHTTP2_TIME_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+/* nghttp2_time_now_sec returns seconds from implementation-specific
+ timepoint. If it is unable to get seconds, it returns 0. */
+uint64_t nghttp2_time_now_sec(void);
+
+#endif /* NGHTTP2_TIME_H */
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 4250ac3..344c542 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -21,6 +21,7 @@ if(HAVE_CUNIT)
nghttp2_npn_test.c
nghttp2_helper_test.c
nghttp2_buf_test.c
+ nghttp2_ratelim_test.c
)
add_executable(main EXCLUDE_FROM_ALL
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c3e4392..c130a00 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -40,14 +40,16 @@ OBJECTS = main.c nghttp2_pq_test.c nghttp2_map_test.c nghttp2_queue_test.c \
nghttp2_hd_test.c \
nghttp2_npn_test.c \
nghttp2_helper_test.c \
- nghttp2_buf_test.c
+ nghttp2_buf_test.c \
+ nghttp2_ratelim_test.c
HFILES = nghttp2_pq_test.h nghttp2_map_test.h nghttp2_queue_test.h \
nghttp2_session_test.h \
nghttp2_frame_test.h nghttp2_stream_test.h nghttp2_hd_test.h \
nghttp2_npn_test.h nghttp2_helper_test.h \
nghttp2_test_helper.h \
- nghttp2_buf_test.h
+ nghttp2_buf_test.h \
+ nghttp2_ratelim_test.h
main_SOURCES = $(HFILES) $(OBJECTS)
diff --git a/tests/main.c b/tests/main.c
index 1f795cd..334cad8 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -40,6 +40,7 @@
#include "nghttp2_npn_test.h"
#include "nghttp2_helper_test.h"
#include "nghttp2_buf_test.h"
+#include "nghttp2_ratelim_test.h"
extern int nghttp2_enable_strict_preface;
@@ -323,6 +324,8 @@ int main() {
test_nghttp2_session_no_closed_streams) ||
!CU_add_test(pSuite, "session_set_stream_user_data",
test_nghttp2_session_set_stream_user_data) ||
+ !CU_add_test(pSuite, "session_stream_reset_ratelim",
+ test_nghttp2_session_stream_reset_ratelim) ||
!CU_add_test(pSuite, "http_mandatory_headers",
test_nghttp2_http_mandatory_headers) ||
!CU_add_test(pSuite, "http_content_length",
@@ -418,7 +421,9 @@ int main() {
!CU_add_test(pSuite, "bufs_advance", test_nghttp2_bufs_advance) ||
!CU_add_test(pSuite, "bufs_next_present",
test_nghttp2_bufs_next_present) ||
- !CU_add_test(pSuite, "bufs_realloc", test_nghttp2_bufs_realloc)) {
+ !CU_add_test(pSuite, "bufs_realloc", test_nghttp2_bufs_realloc) ||
+ !CU_add_test(pSuite, "ratelim_update", test_nghttp2_ratelim_update) ||
+ !CU_add_test(pSuite, "ratelim_drain", test_nghttp2_ratelim_drain)) {
CU_cleanup_registry();
return (int)CU_get_error();
}
diff --git a/tests/nghttp2_ratelim_test.c b/tests/nghttp2_ratelim_test.c
new file mode 100644
index 0000000..6abece9
--- /dev/null
+++ b/tests/nghttp2_ratelim_test.c
@@ -0,0 +1,101 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_ratelim_test.h"
+
+#include <stdio.h>
+
+#include <CUnit/CUnit.h>
+
+#include "nghttp2_ratelim.h"
+
+void test_nghttp2_ratelim_update(void) {
+ nghttp2_ratelim rl;
+
+ nghttp2_ratelim_init(&rl, 1000, 21);
+
+ CU_ASSERT(1000 == rl.val);
+ CU_ASSERT(1000 == rl.burst);
+ CU_ASSERT(21 == rl.rate);
+ CU_ASSERT(0 == rl.tstamp);
+
+ nghttp2_ratelim_update(&rl, 999);
+
+ CU_ASSERT(1000 == rl.val);
+ CU_ASSERT(999 == rl.tstamp);
+
+ nghttp2_ratelim_drain(&rl, 100);
+
+ CU_ASSERT(900 == rl.val);
+
+ nghttp2_ratelim_update(&rl, 1000);
+
+ CU_ASSERT(921 == rl.val);
+
+ nghttp2_ratelim_update(&rl, 1002);
+
+ CU_ASSERT(963 == rl.val);
+
+ nghttp2_ratelim_update(&rl, 1004);
+
+ CU_ASSERT(1000 == rl.val);
+ CU_ASSERT(1004 == rl.tstamp);
+
+ /* timer skew */
+ nghttp2_ratelim_init(&rl, 1000, 21);
+ nghttp2_ratelim_update(&rl, 1);
+
+ CU_ASSERT(1000 == rl.val);
+
+ nghttp2_ratelim_update(&rl, 0);
+
+ CU_ASSERT(1000 == rl.val);
+
+ /* rate * duration overflow */
+ nghttp2_ratelim_init(&rl, 1000, 100);
+ nghttp2_ratelim_drain(&rl, 999);
+
+ CU_ASSERT(1 == rl.val);
+
+ nghttp2_ratelim_update(&rl, UINT64_MAX);
+
+ CU_ASSERT(1000 == rl.val);
+
+ /* val + rate * duration overflow */
+ nghttp2_ratelim_init(&rl, UINT64_MAX - 1, 2);
+ nghttp2_ratelim_update(&rl, 1);
+
+ CU_ASSERT(UINT64_MAX - 1 == rl.val);
+}
+
+void test_nghttp2_ratelim_drain(void) {
+ nghttp2_ratelim rl;
+
+ nghttp2_ratelim_init(&rl, 100, 7);
+
+ CU_ASSERT(-1 == nghttp2_ratelim_drain(&rl, 101));
+ CU_ASSERT(0 == nghttp2_ratelim_drain(&rl, 51));
+ CU_ASSERT(0 == nghttp2_ratelim_drain(&rl, 49));
+ CU_ASSERT(-1 == nghttp2_ratelim_drain(&rl, 1));
+}
diff --git a/tests/nghttp2_ratelim_test.h b/tests/nghttp2_ratelim_test.h
new file mode 100644
index 0000000..02b2f2b
--- /dev/null
+++ b/tests/nghttp2_ratelim_test.h
@@ -0,0 +1,35 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_RATELIM_TEST_H
+#define NGHTTP2_RATELIM_TEST_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+void test_nghttp2_ratelim_update(void);
+void test_nghttp2_ratelim_drain(void);
+
+#endif /* NGHTTP2_RATELIM_TEST_H */
diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c
index ab76ab4..dece5c1 100644
--- a/tests/nghttp2_session_test.c
+++ b/tests/nghttp2_session_test.c
@@ -10790,6 +10790,109 @@ void test_nghttp2_session_set_stream_user_data(void) {
nghttp2_session_del(session);
}
+void test_nghttp2_session_stream_reset_ratelim(void) {
+ nghttp2_session *session;
+ nghttp2_session_callbacks callbacks;
+ nghttp2_frame frame;
+ ssize_t rv;
+ nghttp2_bufs bufs;
+ nghttp2_buf *buf;
+ nghttp2_mem *mem;
+ size_t i;
+ nghttp2_hd_deflater deflater;
+ size_t nvlen;
+ nghttp2_nv *nva;
+ int32_t stream_id;
+ nghttp2_outbound_item *item;
+ nghttp2_option *option;
+
+ mem = nghttp2_mem_default();
+ frame_pack_bufs_init(&bufs);
+
+ memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
+ callbacks.send_callback = null_send_callback;
+
+ nghttp2_option_new(&option);
+ nghttp2_option_set_stream_reset_rate_limit(
+ option, NGHTTP2_DEFAULT_STREAM_RESET_BURST, 0);
+
+ nghttp2_session_server_new2(&session, &callbacks, NULL, option);
+
+ nghttp2_frame_settings_init(&frame.settings, NGHTTP2_FLAG_NONE, NULL, 0);
+ rv = nghttp2_frame_pack_settings(&bufs, &frame.settings);
+
+ CU_ASSERT(0 == rv);
+
+ nghttp2_frame_settings_free(&frame.settings, mem);
+
+ buf = &bufs.head->buf;
+ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
+
+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
+
+ /* Send SETTINGS ACK */
+ rv = nghttp2_session_send(session);
+
+ CU_ASSERT(0 == rv);
+
+ nghttp2_hd_deflate_init(&deflater, mem);
+
+ for (i = 0; i < NGHTTP2_DEFAULT_STREAM_RESET_BURST + 2; ++i) {
+ stream_id = (int32_t)(i * 2 + 1);
+
+ nghttp2_bufs_reset(&bufs);
+
+ /* HEADERS */
+ nvlen = ARRLEN(reqnv);
+ nghttp2_nv_array_copy(&nva, reqnv, nvlen, mem);
+ nghttp2_frame_headers_init(&frame.headers, NGHTTP2_FLAG_END_HEADERS,
+ stream_id, NGHTTP2_HCAT_HEADERS, NULL, nva,
+ nvlen);
+ rv = nghttp2_frame_pack_headers(&bufs, &frame.headers, &deflater);
+
+ CU_ASSERT(0 == rv);
+
+ nghttp2_frame_headers_free(&frame.headers, mem);
+
+ buf = &bufs.head->buf;
+ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
+
+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
+
+ nghttp2_bufs_reset(&bufs);
+
+ /* RST_STREAM */
+ nghttp2_frame_rst_stream_init(&frame.rst_stream, stream_id,
+ NGHTTP2_NO_ERROR);
+ nghttp2_frame_pack_rst_stream(&bufs, &frame.rst_stream);
+ nghttp2_frame_rst_stream_free(&frame.rst_stream);
+
+ buf = &bufs.head->buf;
+ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
+
+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
+
+ if (i < NGHTTP2_DEFAULT_STREAM_RESET_BURST) {
+ CU_ASSERT(0 == nghttp2_outbound_queue_size(&session->ob_reg));
+
+ continue;
+ }
+
+ CU_ASSERT(1 == nghttp2_outbound_queue_size(&session->ob_reg));
+
+ item = nghttp2_session_get_next_ob_item(session);
+
+ CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type);
+ CU_ASSERT(NGHTTP2_DEFAULT_STREAM_RESET_BURST * 2 + 1 ==
+ item->frame.goaway.last_stream_id);
+ }
+
+ nghttp2_hd_deflate_free(&deflater);
+ nghttp2_session_del(session);
+ nghttp2_bufs_free(&bufs);
+ nghttp2_option_del(option);
+}
+
static void check_nghttp2_http_recv_headers_fail(
nghttp2_session *session, nghttp2_hd_deflater *deflater, int32_t stream_id,
int stream_state, const nghttp2_nv *nva, size_t nvlen) {
diff --git a/tests/nghttp2_session_test.h b/tests/nghttp2_session_test.h
index c5095c2..2b74e88 100644
--- a/tests/nghttp2_session_test.h
+++ b/tests/nghttp2_session_test.h
@@ -160,6 +160,7 @@ void test_nghttp2_session_removed_closed_stream(void);
void test_nghttp2_session_pause_data(void);
void test_nghttp2_session_no_closed_streams(void);
void test_nghttp2_session_set_stream_user_data(void);
+void test_nghttp2_session_stream_reset_ratelim(void);
void test_nghttp2_http_mandatory_headers(void);
void test_nghttp2_http_content_length(void);
void test_nghttp2_http_content_length_mismatch(void);
--
2.41.0

View File

@ -1,454 +0,0 @@
From 4b7aefd8fd1612d455f2f128c09230335ed0cee6 Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Tue, 6 Aug 2019 20:48:50 +0900
Subject: [PATCH 1/3] nghttpx: Fix request stall
Fix request stall if backend connection is reused and buffer is full.
Upstream-commit: db2f612a30d54aa152ce5530fa1d683738baa4d1
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
integration-tests/nghttpx_http1_test.go | 29 +++++++++++++++++++++++++
integration-tests/server_tester.go | 4 +++-
src/shrpx_downstream.cc | 12 +++++++++-
src/shrpx_downstream.h | 4 ++++
src/shrpx_http_downstream_connection.cc | 16 +++++++++++++-
src/shrpx_https_upstream.cc | 4 +---
6 files changed, 63 insertions(+), 6 deletions(-)
diff --git a/integration-tests/nghttpx_http1_test.go b/integration-tests/nghttpx_http1_test.go
index a765333..3d41677 100644
--- a/integration-tests/nghttpx_http1_test.go
+++ b/integration-tests/nghttpx_http1_test.go
@@ -625,6 +625,35 @@ func TestH1H1HTTPSRedirectPort(t *testing.T) {
}
}
+// TestH1H1POSTRequests tests that server can handle 2 requests with
+// request body.
+func TestH1H1POSTRequests(t *testing.T) {
+ st := newServerTester(nil, t, noopHandler)
+ defer st.Close()
+
+ res, err := st.http1(requestParam{
+ name: "TestH1H1POSTRequestsNo1",
+ body: make([]byte, 1),
+ })
+ if err != nil {
+ t.Fatalf("Error st.http1() = %v", err)
+ }
+ if got, want := res.status, 200; got != want {
+ t.Errorf("res.status: %v; want %v", got, want)
+ }
+
+ res, err = st.http1(requestParam{
+ name: "TestH1H1POSTRequestsNo2",
+ body: make([]byte, 65536),
+ })
+ if err != nil {
+ t.Fatalf("Error st.http1() = %v", err)
+ }
+ if got, want := res.status, 200; got != want {
+ t.Errorf("res.status: %v; want %v", got, want)
+ }
+}
+
// // TestH1H2ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/2 backend failed.
// func TestH1H2ConnectFailure(t *testing.T) {
diff --git a/integration-tests/server_tester.go b/integration-tests/server_tester.go
index d145519..1156986 100644
--- a/integration-tests/server_tester.go
+++ b/integration-tests/server_tester.go
@@ -662,7 +662,9 @@ func cloneHeader(h http.Header) http.Header {
return h2
}
-func noopHandler(w http.ResponseWriter, r *http.Request) {}
+func noopHandler(w http.ResponseWriter, r *http.Request) {
+ ioutil.ReadAll(r.Body)
+}
type APIResponse struct {
Status string `json:"status,omitempty"`
diff --git a/src/shrpx_downstream.cc b/src/shrpx_downstream.cc
index 360a9a9..48db65b 100644
--- a/src/shrpx_downstream.cc
+++ b/src/shrpx_downstream.cc
@@ -144,7 +144,8 @@ Downstream::Downstream(Upstream *upstream, MemchunkPool *mcpool,
request_header_sent_(false),
accesslog_written_(false),
new_affinity_cookie_(false),
- blocked_request_data_eof_(false) {
+ blocked_request_data_eof_(false),
+ expect_100_continue_(false) {
auto &timeoutconf = get_config()->http2.timeout;
@@ -807,6 +808,11 @@ void Downstream::inspect_http1_request() {
chunked_request_ = true;
}
}
+
+ auto expect = req_.fs.header(http2::HD_EXPECT);
+ expect_100_continue_ =
+ expect &&
+ util::strieq(expect->value, StringRef::from_lit("100-continue"));
}
void Downstream::inspect_http1_response() {
@@ -1103,4 +1109,8 @@ bool Downstream::get_blocked_request_data_eof() const {
return blocked_request_data_eof_;
}
+bool Downstream::get_expect_100_continue() const {
+ return expect_100_continue_;
+}
+
} // namespace shrpx
diff --git a/src/shrpx_downstream.h b/src/shrpx_downstream.h
index c81fcf6..b9a851f 100644
--- a/src/shrpx_downstream.h
+++ b/src/shrpx_downstream.h
@@ -466,6 +466,8 @@ public:
EVENT_TIMEOUT = 0x2,
};
+ bool get_expect_100_continue() const;
+
enum {
DISPATCH_NONE,
DISPATCH_PENDING,
@@ -556,6 +558,8 @@ private:
// true if eof is received from client before sending header fields
// to backend.
bool blocked_request_data_eof_;
+ // true if request contains "expect: 100-continue" header field.
+ bool expect_100_continue_;
};
} // namespace shrpx
diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc
index f50c0f4..85ca947 100644
--- a/src/shrpx_http_downstream_connection.cc
+++ b/src/shrpx_http_downstream_connection.cc
@@ -698,7 +698,8 @@ int HttpDownstreamConnection::push_request_headers() {
// signal_write() when we received request body chunk, and it
// enables us to send headers and data in one writev system call.
if (connect_method || downstream_->get_blocked_request_buf()->rleft() ||
- (!req.http2_expect_body && req.fs.content_length == 0)) {
+ (!req.http2_expect_body && req.fs.content_length == 0) ||
+ downstream_->get_expect_100_continue()) {
signal_write();
}
@@ -1172,6 +1173,19 @@ int HttpDownstreamConnection::write_reuse_first() {
reuse_first_write_done_ = true;
+ // upstream->resume_read() might be called in
+ // write_tls()/write_clear(), but before blocked_request_buf_ is
+ // reset. So upstream read might still be blocked. Let's do it
+ // again here.
+ auto input = downstream_->get_request_buf();
+ if (input->rleft() == 0) {
+ auto upstream = downstream_->get_upstream();
+ auto &req = downstream_->request();
+
+ upstream->resume_read(SHRPX_NO_BUFFER, downstream_,
+ req.unconsumed_body_length);
+ }
+
return 0;
}
diff --git a/src/shrpx_https_upstream.cc b/src/shrpx_https_upstream.cc
index 452ec90..96ca2cd 100644
--- a/src/shrpx_https_upstream.cc
+++ b/src/shrpx_https_upstream.cc
@@ -467,9 +467,7 @@ int htp_hdrs_completecb(http_parser *htp) {
// and let them decide whether responds with 100 Continue or not.
// For alternative mode, we have no backend, so just send 100
// Continue here to make the client happy.
- auto expect = req.fs.header(http2::HD_EXPECT);
- if (expect &&
- util::strieq(expect->value, StringRef::from_lit("100-continue"))) {
+ if (downstream->get_expect_100_continue()) {
auto output = downstream->get_response_buf();
constexpr auto res = StringRef::from_lit("HTTP/1.1 100 Continue\r\n\r\n");
output->append(res);
--
2.20.1
From 589a98eba0b3c7a4dbb2262c60b609cac2b1f838 Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Tue, 25 Jun 2019 22:33:35 +0900
Subject: [PATCH 2/3] Add nghttp2_option_set_max_outbound_ack
Upstream-commit: a76d0723b5f52902139ff453e0ec840673e86e75
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
doc/Makefile.am | 1 +
lib/includes/nghttp2/nghttp2.h | 11 +++++++++++
lib/nghttp2_option.c | 5 +++++
lib/nghttp2_option.h | 5 +++++
lib/nghttp2_session.c | 9 +++++++--
lib/nghttp2_session.h | 8 ++++++--
tests/nghttp2_session_test.c | 4 ++--
7 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 07cd34e..66e5ba3 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -67,6 +67,7 @@ APIDOCS= \
nghttp2_option_set_no_recv_client_magic.rst \
nghttp2_option_set_peer_max_concurrent_streams.rst \
nghttp2_option_set_user_recv_extension_type.rst \
+ nghttp2_option_set_max_outbound_ack.rst \
nghttp2_pack_settings_payload.rst \
nghttp2_priority_spec_check_default.rst \
nghttp2_priority_spec_default_init.rst \
diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h
index 14f8950..137a675 100644
--- a/lib/includes/nghttp2/nghttp2.h
+++ b/lib/includes/nghttp2/nghttp2.h
@@ -2637,6 +2637,17 @@ nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option,
int val);
+/**
+ * @function
+ *
+ * This function sets the maximum number of outgoing SETTINGS ACK and
+ * PING ACK frames retained in :type:`nghttp2_session` object. If
+ * more than those frames are retained, the peer is considered to be
+ * misbehaving and session will be closed. The default value is 1000.
+ */
+NGHTTP2_EXTERN void nghttp2_option_set_max_outbound_ack(nghttp2_option *option,
+ size_t val);
+
/**
* @function
*
diff --git a/lib/nghttp2_option.c b/lib/nghttp2_option.c
index aec5dcf..ae22493 100644
--- a/lib/nghttp2_option.c
+++ b/lib/nghttp2_option.c
@@ -116,3 +116,8 @@ void nghttp2_option_set_no_closed_streams(nghttp2_option *option, int val) {
option->opt_set_mask |= NGHTTP2_OPT_NO_CLOSED_STREAMS;
option->no_closed_streams = val;
}
+
+void nghttp2_option_set_max_outbound_ack(nghttp2_option *option, size_t val) {
+ option->opt_set_mask |= NGHTTP2_OPT_MAX_OUTBOUND_ACK;
+ option->max_outbound_ack = val;
+}
diff --git a/lib/nghttp2_option.h b/lib/nghttp2_option.h
index c743e33..86d31f7 100644
--- a/lib/nghttp2_option.h
+++ b/lib/nghttp2_option.h
@@ -66,6 +66,7 @@ typedef enum {
NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8,
NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10,
+ NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11,
} nghttp2_option_flag;
/**
@@ -80,6 +81,10 @@ struct nghttp2_option {
* NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE
*/
size_t max_deflate_dynamic_table_size;
+ /**
+ * NGHTTP2_OPT_MAX_OUTBOUND_ACK
+ */
+ size_t max_outbound_ack;
/**
* Bitwise OR of nghttp2_option_flag to determine that which fields
* are specified.
diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c
index c58f059..8628cc7 100644
--- a/lib/nghttp2_session.c
+++ b/lib/nghttp2_session.c
@@ -457,6 +457,7 @@ static int session_new(nghttp2_session **session_ptr,
(*session_ptr)->remote_settings.max_concurrent_streams = 100;
(*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN;
+ (*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM;
if (option) {
if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) &&
@@ -516,6 +517,10 @@ static int session_new(nghttp2_session **session_ptr,
option->no_closed_streams) {
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_CLOSED_STREAMS;
}
+
+ if (option->opt_set_mask & NGHTTP2_OPT_MAX_OUTBOUND_ACK) {
+ (*session_ptr)->max_outbound_ack = option->max_outbound_ack;
+ }
}
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
@@ -6831,7 +6836,7 @@ int nghttp2_session_add_ping(nghttp2_session *session, uint8_t flags,
mem = &session->mem;
if ((flags & NGHTTP2_FLAG_ACK) &&
- session->obq_flood_counter_ >= NGHTTP2_MAX_OBQ_FLOOD_ITEM) {
+ session->obq_flood_counter_ >= session->max_outbound_ack) {
return NGHTTP2_ERR_FLOODED;
}
@@ -6976,7 +6981,7 @@ int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
- if (session->obq_flood_counter_ >= NGHTTP2_MAX_OBQ_FLOOD_ITEM) {
+ if (session->obq_flood_counter_ >= session->max_outbound_ack) {
return NGHTTP2_ERR_FLOODED;
}
}
diff --git a/lib/nghttp2_session.h b/lib/nghttp2_session.h
index c7cb27d..d9e2846 100644
--- a/lib/nghttp2_session.h
+++ b/lib/nghttp2_session.h
@@ -97,7 +97,7 @@ typedef struct {
response frames are stacked up, which leads to memory exhaustion.
The value selected here is arbitrary, but safe value and if we have
these frames in this number, it is considered suspicious. */
-#define NGHTTP2_MAX_OBQ_FLOOD_ITEM 10000
+#define NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM 1000
/* The default value of maximum number of concurrent streams. */
#define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
@@ -260,8 +260,12 @@ struct nghttp2_session {
size_t num_idle_streams;
/* The number of bytes allocated for nvbuf */
size_t nvbuflen;
- /* Counter for detecting flooding in outbound queue */
+ /* Counter for detecting flooding in outbound queue. If it exceeds
+ max_outbound_ack, session will be closed. */
size_t obq_flood_counter_;
+ /* The maximum number of outgoing SETTINGS ACK and PING ACK in
+ outbound queue. */
+ size_t max_outbound_ack;
/* The maximum length of header block to send. Calculated by the
same way as nghttp2_hd_deflate_bound() does. */
size_t max_send_header_block_length;
diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c
index 783b0ed..debec59 100644
--- a/tests/nghttp2_session_test.c
+++ b/tests/nghttp2_session_test.c
@@ -9894,7 +9894,7 @@ void test_nghttp2_session_flooding(void) {
buf = &bufs.head->buf;
- for (i = 0; i < NGHTTP2_MAX_OBQ_FLOOD_ITEM; ++i) {
+ for (i = 0; i < NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM; ++i) {
CU_ASSERT(
(ssize_t)nghttp2_buf_len(buf) ==
nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf)));
@@ -9916,7 +9916,7 @@ void test_nghttp2_session_flooding(void) {
buf = &bufs.head->buf;
- for (i = 0; i < NGHTTP2_MAX_OBQ_FLOOD_ITEM; ++i) {
+ for (i = 0; i < NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM; ++i) {
CU_ASSERT(
(ssize_t)nghttp2_buf_len(buf) ==
nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf)));
--
2.20.1
From e32b3e4c9df4abb83ca1c1c41901fadbae44699b Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Tue, 25 Jun 2019 22:38:43 +0900
Subject: [PATCH 3/3] Don't read too greedily
Upstream-commit: 83d362c6d21f76599b86e7b94cd1992288a1d43c
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
src/HttpServer.cc | 2 ++
src/shrpx_client_handler.cc | 9 +++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/HttpServer.cc b/src/HttpServer.cc
index b3e35ef..a75cee4 100644
--- a/src/HttpServer.cc
+++ b/src/HttpServer.cc
@@ -650,6 +650,7 @@ int Http2Handler::read_clear() {
}
return -1;
}
+ break;
}
return write_(*this);
@@ -775,6 +776,7 @@ int Http2Handler::read_tls() {
}
return -1;
}
+ break;
}
fin:
diff --git a/src/shrpx_client_handler.cc b/src/shrpx_client_handler.cc
index 21430dd..fa1fc87 100644
--- a/src/shrpx_client_handler.cc
+++ b/src/shrpx_client_handler.cc
@@ -111,6 +111,7 @@ void writecb(struct ev_loop *loop, ev_io *w, int revents) {
int ClientHandler::noop() { return 0; }
int ClientHandler::read_clear() {
+ auto should_break = false;
rb_.ensure_chunk();
for (;;) {
if (rb_.rleft() && on_read() != 0) {
@@ -123,7 +124,7 @@ int ClientHandler::read_clear() {
return 0;
}
- if (!ev_is_active(&conn_.rev)) {
+ if (!ev_is_active(&conn_.rev) || should_break) {
return 0;
}
@@ -141,6 +142,7 @@ int ClientHandler::read_clear() {
}
rb_.write(nread);
+ should_break = true;
}
}
@@ -205,6 +207,8 @@ int ClientHandler::tls_handshake() {
}
int ClientHandler::read_tls() {
+ auto should_break = false;
+
ERR_clear_error();
rb_.ensure_chunk();
@@ -221,7 +225,7 @@ int ClientHandler::read_tls() {
return 0;
}
- if (!ev_is_active(&conn_.rev)) {
+ if (!ev_is_active(&conn_.rev) || should_break) {
return 0;
}
@@ -239,6 +243,7 @@ int ClientHandler::read_tls() {
}
rb_.write(nread);
+ should_break = true;
}
}
--
2.20.1

View File

@ -1,340 +0,0 @@
From 34670cfbc56f1c63ec046c38b9ad518010b5c84d Mon Sep 17 00:00:00 2001
From: James M Snell <jasnell@gmail.com>
Date: Fri, 17 Apr 2020 16:53:51 -0700
Subject: [PATCH 1/2] Implement max settings option
Upstream-commit: 336a98feb0d56b9ac54e12736b18785c27f75090
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
doc/CMakeLists.txt | 1 +
doc/Makefile.am | 1 +
lib/includes/nghttp2/nghttp2.h | 23 +++++++++++++
lib/nghttp2_helper.c | 2 ++
lib/nghttp2_option.c | 5 +++
lib/nghttp2_option.h | 5 +++
lib/nghttp2_session.c | 21 ++++++++++++
lib/nghttp2_session.h | 2 ++
tests/main.c | 2 ++
tests/nghttp2_session_test.c | 61 ++++++++++++++++++++++++++++++++++
tests/nghttp2_session_test.h | 1 +
11 files changed, 124 insertions(+)
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 34c0279..f3aec84 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -42,6 +42,7 @@ set(APIDOCS
nghttp2_option_set_no_recv_client_magic.rst
nghttp2_option_set_peer_max_concurrent_streams.rst
nghttp2_option_set_user_recv_extension_type.rst
+ nghttp2_option_set_max_settings.rst
nghttp2_pack_settings_payload.rst
nghttp2_priority_spec_check_default.rst
nghttp2_priority_spec_default_init.rst
diff --git a/doc/Makefile.am b/doc/Makefile.am
index c17d933..5a58f8e 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -68,6 +68,7 @@ APIDOCS= \
nghttp2_option_set_peer_max_concurrent_streams.rst \
nghttp2_option_set_user_recv_extension_type.rst \
nghttp2_option_set_max_outbound_ack.rst \
+ nghttp2_option_set_max_settings.rst \
nghttp2_pack_settings_payload.rst \
nghttp2_priority_spec_check_default.rst \
nghttp2_priority_spec_default_init.rst \
diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h
index d79bf48..b0ff6c5 100644
--- a/lib/includes/nghttp2/nghttp2.h
+++ b/lib/includes/nghttp2/nghttp2.h
@@ -222,6 +222,13 @@ typedef struct {
*/
#define NGHTTP2_CLIENT_MAGIC_LEN 24
+/**
+ * @macro
+ *
+ * The default max number of settings per SETTINGS frame
+ */
+#define NGHTTP2_DEFAULT_MAX_SETTINGS 32
+
/**
* @enum
*
@@ -392,6 +399,11 @@ typedef enum {
* receives an other type of frame.
*/
NGHTTP2_ERR_SETTINGS_EXPECTED = -536,
+ /**
+ * When a local endpoint receives too many settings entries
+ * in a single SETTINGS frame.
+ */
+ NGHTTP2_ERR_TOO_MANY_SETTINGS = -537,
/**
* The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is
* under unexpected condition and processing was terminated (e.g.,
@@ -2648,6 +2660,17 @@ NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option,
NGHTTP2_EXTERN void nghttp2_option_set_max_outbound_ack(nghttp2_option *option,
size_t val);
+/**
+ * @function
+ *
+ * This function sets the maximum number of SETTINGS entries per
+ * SETTINGS frame that will be accepted. If more than those entries
+ * are received, the peer is considered to be misbehaving and session
+ * will be closed. The default value is 32.
+ */
+NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option,
+ size_t val);
+
/**
* @function
*
diff --git a/lib/nghttp2_helper.c b/lib/nghttp2_helper.c
index 3b282c7..49bbf07 100644
--- a/lib/nghttp2_helper.c
+++ b/lib/nghttp2_helper.c
@@ -334,6 +334,8 @@ const char *nghttp2_strerror(int error_code) {
case NGHTTP2_ERR_FLOODED:
return "Flooding was detected in this HTTP/2 session, and it must be "
"closed";
+ case NGHTTP2_ERR_TOO_MANY_SETTINGS:
+ return "SETTINGS frame contained more than the maximum allowed entries";
default:
return "Unknown error code";
}
diff --git a/lib/nghttp2_option.c b/lib/nghttp2_option.c
index e53f22d..34348e6 100644
--- a/lib/nghttp2_option.c
+++ b/lib/nghttp2_option.c
@@ -121,3 +121,8 @@ void nghttp2_option_set_max_outbound_ack(nghttp2_option *option, size_t val) {
option->opt_set_mask |= NGHTTP2_OPT_MAX_OUTBOUND_ACK;
option->max_outbound_ack = val;
}
+
+void nghttp2_option_set_max_settings(nghttp2_option *option, size_t val) {
+ option->opt_set_mask |= NGHTTP2_OPT_MAX_SETTINGS;
+ option->max_settings = val;
+}
diff --git a/lib/nghttp2_option.h b/lib/nghttp2_option.h
index 1f740aa..939729f 100644
--- a/lib/nghttp2_option.h
+++ b/lib/nghttp2_option.h
@@ -67,6 +67,7 @@ typedef enum {
NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10,
NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11,
+ NGHTTP2_OPT_MAX_SETTINGS = 1 << 12,
} nghttp2_option_flag;
/**
@@ -85,6 +86,10 @@ struct nghttp2_option {
* NGHTTP2_OPT_MAX_OUTBOUND_ACK
*/
size_t max_outbound_ack;
+ /**
+ * NGHTTP2_OPT_MAX_SETTINGS
+ */
+ size_t max_settings;
/**
* Bitwise OR of nghttp2_option_flag to determine that which fields
* are specified.
diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c
index 670f83f..7638823 100644
--- a/lib/nghttp2_session.c
+++ b/lib/nghttp2_session.c
@@ -458,6 +458,7 @@ static int session_new(nghttp2_session **session_ptr,
(*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN;
(*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM;
+ (*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS;
if (option) {
if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) &&
@@ -521,6 +522,11 @@ static int session_new(nghttp2_session **session_ptr,
if (option->opt_set_mask & NGHTTP2_OPT_MAX_OUTBOUND_ACK) {
(*session_ptr)->max_outbound_ack = option->max_outbound_ack;
}
+
+ if ((option->opt_set_mask & NGHTTP2_OPT_MAX_SETTINGS) &&
+ option->max_settings) {
+ (*session_ptr)->max_settings = option->max_settings;
+ }
}
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
@@ -5658,6 +5664,16 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
iframe->max_niv =
iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1;
+ if (iframe->max_niv - 1 > session->max_settings) {
+ rv = nghttp2_session_terminate_session_with_reason(
+ session, NGHTTP2_ENHANCE_YOUR_CALM,
+ "SETTINGS: too many setting entries");
+ if (nghttp2_is_fatal(rv)) {
+ return rv;
+ }
+ return (ssize_t)inlen;
+ }
+
iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) *
iframe->max_niv);
@@ -7413,6 +7429,11 @@ static int nghttp2_session_upgrade_internal(nghttp2_session *session,
if (settings_payloadlen % NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
+ /* SETTINGS frame contains too many settings */
+ if (settings_payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH
+ > session->max_settings) {
+ return NGHTTP2_ERR_TOO_MANY_SETTINGS;
+ }
rv = nghttp2_frame_unpack_settings_payload2(&iv, &niv, settings_payload,
settings_payloadlen, mem);
if (rv != 0) {
diff --git a/lib/nghttp2_session.h b/lib/nghttp2_session.h
index 2969364..e62a3bb 100644
--- a/lib/nghttp2_session.h
+++ b/lib/nghttp2_session.h
@@ -269,6 +269,8 @@ struct nghttp2_session {
/* The maximum length of header block to send. Calculated by the
same way as nghttp2_hd_deflate_bound() does. */
size_t max_send_header_block_length;
+ /* The maximum number of settings accepted per SETTINGS frame. */
+ size_t max_settings;
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
uint32_t next_stream_id;
/* The last stream ID this session initiated. For client session,
diff --git a/tests/main.c b/tests/main.c
index 13865de..1f795cd 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -313,6 +313,8 @@ int main() {
test_nghttp2_session_set_local_window_size) ||
!CU_add_test(pSuite, "session_cancel_from_before_frame_send",
test_nghttp2_session_cancel_from_before_frame_send) ||
+ !CU_add_test(pSuite, "session_too_many_settings",
+ test_nghttp2_session_too_many_settings) ||
!CU_add_test(pSuite, "session_removed_closed_stream",
test_nghttp2_session_removed_closed_stream) ||
!CU_add_test(pSuite, "session_pause_data",
diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c
index 0013e92..ab76ab4 100644
--- a/tests/nghttp2_session_test.c
+++ b/tests/nghttp2_session_test.c
@@ -10450,6 +10450,67 @@ void test_nghttp2_session_cancel_from_before_frame_send(void) {
nghttp2_session_del(session);
}
+void test_nghttp2_session_too_many_settings(void) {
+ nghttp2_session *session;
+ nghttp2_option *option;
+ nghttp2_session_callbacks callbacks;
+ nghttp2_frame frame;
+ nghttp2_bufs bufs;
+ nghttp2_buf *buf;
+ ssize_t rv;
+ my_user_data ud;
+ nghttp2_settings_entry iv[3];
+ nghttp2_mem *mem;
+ nghttp2_outbound_item *item;
+
+ mem = nghttp2_mem_default();
+ frame_pack_bufs_init(&bufs);
+
+ memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
+ callbacks.on_frame_recv_callback = on_frame_recv_callback;
+ callbacks.send_callback = null_send_callback;
+
+ nghttp2_option_new(&option);
+ nghttp2_option_set_max_settings(option, 1);
+
+ nghttp2_session_client_new2(&session, &callbacks, &ud, option);
+
+ CU_ASSERT(1 == session->max_settings);
+
+ nghttp2_option_del(option);
+
+ iv[0].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
+ iv[0].value = 3000;
+
+ iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
+ iv[1].value = 16384;
+
+ nghttp2_frame_settings_init(&frame.settings, NGHTTP2_FLAG_NONE, dup_iv(iv, 2),
+ 2);
+
+ rv = nghttp2_frame_pack_settings(&bufs, &frame.settings);
+
+ CU_ASSERT(0 == rv);
+ CU_ASSERT(nghttp2_bufs_len(&bufs) > 0);
+
+ nghttp2_frame_settings_free(&frame.settings, mem);
+
+ buf = &bufs.head->buf;
+ assert(nghttp2_bufs_len(&bufs) == nghttp2_buf_len(buf));
+
+ ud.frame_recv_cb_called = 0;
+
+ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
+
+ item = nghttp2_session_get_next_ob_item(session);
+ CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type);
+
+ nghttp2_bufs_reset(&bufs);
+ nghttp2_bufs_free(&bufs);
+ nghttp2_session_del(session);
+}
+
static void
prepare_session_removed_closed_stream(nghttp2_session *session,
nghttp2_hd_deflater *deflater) {
diff --git a/tests/nghttp2_session_test.h b/tests/nghttp2_session_test.h
index 35a48b8..c5095c2 100644
--- a/tests/nghttp2_session_test.h
+++ b/tests/nghttp2_session_test.h
@@ -155,6 +155,7 @@ void test_nghttp2_session_repeated_priority_change(void);
void test_nghttp2_session_repeated_priority_submission(void);
void test_nghttp2_session_set_local_window_size(void);
void test_nghttp2_session_cancel_from_before_frame_send(void);
+void test_nghttp2_session_too_many_settings(void);
void test_nghttp2_session_removed_closed_stream(void);
void test_nghttp2_session_pause_data(void);
void test_nghttp2_session_no_closed_streams(void);
--
2.21.3
From da3f4a5730ffa015a9e2d62e6e876a02f1dced20 Mon Sep 17 00:00:00 2001
From: James M Snell <jasnell@gmail.com>
Date: Sun, 19 Apr 2020 09:12:24 -0700
Subject: [PATCH 2/2] Earlier check for settings flood
Upstream-commit: f8da73bd042f810f34d19f9eae02b46d870af394
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/nghttp2_session.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c
index 7638823..8271198 100644
--- a/lib/nghttp2_session.c
+++ b/lib/nghttp2_session.c
@@ -5654,6 +5654,12 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
break;
}
+ /* Check the settings flood counter early to be safe */
+ if (session->obq_flood_counter_ >= session->max_outbound_ack &&
+ !(iframe->frame.hd.flags & NGHTTP2_FLAG_ACK)) {
+ return NGHTTP2_ERR_FLOODED;
+ }
+
iframe->state = NGHTTP2_IB_READ_SETTINGS;
if (iframe->payloadleft) {
--
2.21.3

View File

@ -1,323 +0,0 @@
Summary: Experimental HTTP/2 client, server and proxy
Name: nghttp2
Version: 1.33.0
Release: 5%{?dist}
License: MIT
Group: Applications/Internet
URL: https://nghttp2.org/
Source0: https://github.com/tatsuhiro-t/nghttp2/releases/download/v%{version}/nghttp2-%{version}.tar.xz
# backport security fixes from nghttp2-1.39.2 (CVE-2019-9511 and CVE-2019-9513)
Patch1: nghttp2-1.31.1-CVE-2019-9511-and-CVE-2019-9513.patch
# prevent DoS caused by overly large SETTINGS frames (CVE-2020-11080)
Patch2: nghttp2-1.33.0-CVE-2020-11080.patch
# fix HTTP/2 Rapid Reset (CVE-2023-44487)
Patch3: 0003-nghttp2-1.33.0-CVE-2023-44487.patch
BuildRequires: automake
BuildRequires: libtool
BuildRequires: CUnit-devel
BuildRequires: c-ares-devel
BuildRequires: gcc-c++
BuildRequires: libev-devel
BuildRequires: openssl-devel
BuildRequires: python3-devel
BuildRequires: systemd-devel
BuildRequires: zlib-devel
Requires: libnghttp2%{?_isa} = %{version}-%{release}
%{?systemd_requires}
%description
This package contains the HTTP/2 client, server and proxy programs.
%package -n libnghttp2
Summary: A library implementing the HTTP/2 protocol
Group: Development/Libraries
%description -n libnghttp2
libnghttp2 is a library implementing the Hypertext Transfer Protocol
version 2 (HTTP/2) protocol in C.
%package -n libnghttp2-devel
Summary: Files needed for building applications with libnghttp2
Group: Development/Libraries
Requires: libnghttp2%{?_isa} = %{version}-%{release}
Requires: pkgconfig
%description -n libnghttp2-devel
The libnghttp2-devel package includes libraries and header files needed
for building applications with libnghttp2.
%prep
%setup -q
%patch1 -p1
%patch2 -p1
%patch3 -p1
autoreconf -fiv
# make fetch-ocsp-response use Python 3
sed -e '1 s|^#!/.*python|&3|' -i script/fetch-ocsp-response
%build
%configure PYTHON=%{__python3} \
--disable-python-bindings \
--disable-static \
--without-libxml2 \
--without-spdylay
# avoid using rpath
sed -i libtool \
-e 's/^runpath_var=.*/runpath_var=/' \
-e 's/^hardcode_libdir_flag_spec=".*"$/hardcode_libdir_flag_spec=""/'
make %{?_smp_mflags} V=1
%install
%make_install
install -D -m0444 -p contrib/nghttpx.service \
"$RPM_BUILD_ROOT%{_unitdir}/nghttpx.service"
# not needed on Fedora/RHEL
rm -f "$RPM_BUILD_ROOT%{_libdir}/libnghttp2.la"
# will be installed via %%doc
rm -f "$RPM_BUILD_ROOT%{_datadir}/doc/nghttp2/README.rst"
%ldconfig_scriptlets -n libnghttp2
%post
%systemd_post nghttpx.service
%postun
%systemd_postun nghttpx.service
%check
# test the just built library instead of the system one, without using rpath
export "LD_LIBRARY_PATH=$RPM_BUILD_ROOT%{_libdir}:$LD_LIBRARY_PATH"
make %{?_smp_mflags} check
%files
%{_bindir}/h2load
%{_bindir}/nghttp
%{_bindir}/nghttpd
%{_bindir}/nghttpx
%{_datadir}/nghttp2
%{_mandir}/man1/h2load.1*
%{_mandir}/man1/nghttp.1*
%{_mandir}/man1/nghttpd.1*
%{_mandir}/man1/nghttpx.1*
%{_unitdir}/nghttpx.service
%files -n libnghttp2
%{_libdir}/libnghttp2.so.*
%{!?_licensedir:%global license %%doc}
%license COPYING
%files -n libnghttp2-devel
%{_includedir}/nghttp2
%{_libdir}/pkgconfig/libnghttp2.pc
%{_libdir}/libnghttp2.so
%doc README.rst
%changelog
* Fri Oct 13 2023 Jan Macku <jamacku@redhat.com> - 1.33.0-5
- fix HTTP/2 Rapid Reset (CVE-2023-44487)
* Tue Jun 09 2020 Kamil Dudka <kdudka@redhat.com> 1.33.0-4
- prevent DoS caused by overly large SETTINGS frames (CVE-2020-11080)
* Wed Aug 28 2019 Kamil Dudka <kdudka@redhat.com> 1.33.0-3
- rebuild to trigger gating (#1681044)
* Mon Aug 19 2019 Kamil Dudka <kdudka@redhat.com> 1.33.0-2
- backport security fixes from nghttp2-1.39.2 (CVE-2019-9511 and CVE-2019-9513)
* Tue Oct 09 2018 Kamil Dudka <kdudka@redhat.com> 1.33.0-1
- use python3 for build
- update to the latest upstream release (#1636992)
* Wed May 09 2018 Kamil Dudka <kdudka@redhat.com> 1.32.0-1
- update to the latest upstream release
* Fri Apr 13 2018 Kamil Dudka <kdudka@redhat.com> 1.31.1-1
- update to the latest upstream release (fixes CVE-2018-1000168)
* Thu Mar 15 2018 Kamil Dudka <kdudka@redhat.com> 1.31.0-2
- make fetch-ocsp-response use Python 3
* Tue Feb 27 2018 Kamil Dudka <kdudka@redhat.com> 1.31.0-1
- update to the latest upstream release
* Mon Feb 19 2018 Kamil Dudka <kdudka@redhat.com> 1.30.0-3
- add explicit BR for the gcc-c++ compiler
* Thu Feb 08 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.30.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Mon Feb 05 2018 Kamil Dudka <kdudka@redhat.com> 1.30.0-1
- update to the latest upstream release
* Sat Feb 03 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.29.0-2
- Switch to %%ldconfig_scriptlets
* Tue Dec 19 2017 Kamil Dudka <kdudka@redhat.com> 1.29.0-1
- update to the latest upstream release
* Sun Nov 26 2017 Kamil Dudka <kdudka@redhat.com> 1.28.0-1
- update to the latest upstream release
* Wed Oct 25 2017 Kamil Dudka <kdudka@redhat.com> 1.27.0-1
- update to the latest upstream release
* Wed Sep 20 2017 Kamil Dudka <kdudka@redhat.com> 1.26.0-1
- update to the latest upstream release
* Fri Aug 18 2017 Kamil Dudka <kdudka@redhat.com> 1.25.0-1
- update to the latest upstream release
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.24.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
* Sat Jul 29 2017 Florian Weimer <fweimer@redhat.com> - 1.24.0-3
- Rebuild with binutils fix for ppc64le (#1475636)
* Wed Jul 26 2017 Kamil Dudka <kdudka@redhat.com> 1.24.0-2
- drop workaround for a GCC bug that has been fixed (#1358845)
* Sun Jul 02 2017 Kamil Dudka <kdudka@redhat.com> 1.24.0-1
- update to the latest upstream release
* Tue May 30 2017 Kamil Dudka <kdudka@redhat.com> 1.23.1-1
- update to the latest upstream release
* Sat May 27 2017 Kamil Dudka <kdudka@redhat.com> 1.23.0-1
- update to the latest upstream release
* Mon Apr 24 2017 Kamil Dudka <kdudka@redhat.com> 1.22.0-1
- update to the latest upstream release
* Mon Apr 10 2017 Kamil Dudka <kdudka@redhat.com> 1.21.1-1
- update to the latest upstream release
* Mon Mar 27 2017 Kamil Dudka <kdudka@redhat.com> 1.21.0-1
- update to the latest upstream release
* Sun Feb 26 2017 Tomasz Torcz <ttorcz@fedoraproject.org> - 1.20.0-1
- package systemd unit file (#1426929)
- update to latest upstream release
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.19.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Wed Jan 25 2017 Kamil Dudka <kdudka@redhat.com> 1.19.0-1
- update to the latest upstream release
* Thu Jan 05 2017 Kamil Dudka <kdudka@redhat.com> 1.18.1-1
- update to the latest upstream release
* Tue Dec 27 2016 Kamil Dudka <kdudka@redhat.com> 1.18.0-1
- update to the latest upstream release (requires c-ares for apps)
* Mon Nov 28 2016 Kamil Dudka <kdudka@redhat.com> 1.17.0-1
- update to the latest upstream release
* Tue Nov 15 2016 Kamil Dudka <kdudka@redhat.com> 1.16.1-1
- update to the latest upstream release
* Mon Oct 24 2016 Kamil Dudka <kdudka@redhat.com> 1.16.0-1
- update to the latest upstream release
* Mon Sep 26 2016 Kamil Dudka <kdudka@redhat.com> 1.15.0-1
- update to the latest upstream release
* Mon Sep 12 2016 Kamil Dudka <kdudka@redhat.com> 1.14.1-1
- update to the latest upstream release
* Thu Aug 25 2016 Kamil Dudka <kdudka@redhat.com> 1.14.0-1
- update to the latest upstream release
* Tue Jul 26 2016 Kamil Dudka <kdudka@redhat.com> 1.13.0-2
- prevent nghttpx from crashing on armv7hl (#1358845)
* Thu Jul 21 2016 Kamil Dudka <kdudka@redhat.com> 1.13.0-1
- update to the latest upstream release
* Mon Jun 27 2016 Kamil Dudka <kdudka@redhat.com> 1.12.0-1
- update to the latest upstream release
* Sun May 29 2016 Kamil Dudka <kdudka@redhat.com> 1.11.1-1
- update to the latest upstream release
* Thu May 26 2016 Kamil Dudka <kdudka@redhat.com> 1.11.0-1
- update to the latest upstream release
* Mon Apr 25 2016 Kamil Dudka <kdudka@redhat.com> 1.10.0-1
- update to the latest upstream release
* Sun Apr 03 2016 Kamil Dudka <kdudka@redhat.com> 1.9.2-1
- update to the latest upstream release
* Tue Mar 29 2016 Kamil Dudka <kdudka@redhat.com> 1.9.1-1
- update to the latest upstream release
* Thu Feb 25 2016 Kamil Dudka <kdudka@redhat.com> 1.8.0-1
- update to the latest upstream release
* Thu Feb 11 2016 Kamil Dudka <kdudka@redhat.com> 1.7.1-1
- update to the latest upstream release (fixes CVE-2016-1544)
* Fri Feb 05 2016 Kamil Dudka <kdudka@redhat.com> 1.7.0-3
- make the package compile with gcc-6
* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 1.7.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Mon Jan 25 2016 Kamil Dudka <kdudka@redhat.com> 1.7.0-1
- update to the latest upstream release
* Fri Dec 25 2015 Kamil Dudka <kdudka@redhat.com> 1.6.0-1
- update to the latest upstream release (fixes CVE-2015-8659)
* Thu Nov 26 2015 Kamil Dudka <kdudka@redhat.com> 1.5.0-1
- update to the latest upstream release
* Mon Oct 26 2015 Kamil Dudka <kdudka@redhat.com> 1.4.0-1
- update to the latest upstream release
* Thu Sep 24 2015 Kamil Dudka <kdudka@redhat.com> 1.3.4-1
- update to the latest upstream release
* Wed Sep 23 2015 Kamil Dudka <kdudka@redhat.com> 1.3.3-1
- update to the latest upstream release
* Wed Sep 16 2015 Kamil Dudka <kdudka@redhat.com> 1.3.2-1
- update to the latest upstream release
* Mon Sep 14 2015 Kamil Dudka <kdudka@redhat.com> 1.3.1-1
- update to the latest upstream release
* Mon Aug 31 2015 Kamil Dudka <kdudka@redhat.com> 1.3.0-1
- update to the latest upstream release
* Mon Aug 17 2015 Kamil Dudka <kdudka@redhat.com> 1.2.1-1
- update to the latest upstream release
* Sun Aug 09 2015 Kamil Dudka <kdudka@redhat.com> 1.2.0-1
- update to the latest upstream release
* Wed Jul 15 2015 Kamil Dudka <kdudka@redhat.com> 1.1.1-1
- update to the latest upstream release
* Tue Jun 30 2015 Kamil Dudka <kdudka@redhat.com> 1.0.5-1
- packaged for Fedora (#1237247)

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

566
nghttp2.spec Normal file
View File

@ -0,0 +1,566 @@
%global with_mingw 0
%if 0%{?fedora}
%global with_mingw 1
%endif
Summary: Experimental HTTP/2 client, server and proxy
Name: nghttp2
Version: 1.61.0
Release: 2%{?dist}
# Parts of ruby bindings are additionally under GPL-2.0-or-later, MIT and
# HPND-Kevlin-Henney but they are NOT shipped.
License: MIT
URL: https://nghttp2.org/
Source0: https://github.com/tatsuhiro-t/nghttp2/releases/download/v%{version}/nghttp2-%{version}.tar.xz
Source1: https://github.com/%{name}/%{name}/releases/download/v%{version}/%{name}-%{version}.tar.xz.asc
Source2: tatsuhiro-t.pgp
BuildRequires: CUnit-devel
BuildRequires: c-ares-devel
BuildRequires: gcc-c++
BuildRequires: libev-devel
BuildRequires: libxml2-devel
BuildRequires: make
BuildRequires: openssl-devel
BuildRequires: python3-devel
BuildRequires: systemd-rpm-macros
BuildRequires: zlib-devel
# For gpg verification of source tarball
BuildRequires: gnupg2
Requires: libnghttp2%{?_isa} = %{version}-%{release}
%{?systemd_requires}
%if %{with_mingw}
BuildRequires: mingw32-filesystem >= 107
BuildRequires: mingw32-gcc-c++
BuildRequires: mingw32-binutils
BuildRequires: mingw32-c-ares
BuildRequires: mingw32-libxml2
BuildRequires: mingw32-openssl
BuildRequires: mingw32-python3
BuildRequires: mingw32-zlib
BuildRequires: mingw64-filesystem >= 107
BuildRequires: mingw64-gcc-c++
BuildRequires: mingw64-binutils
BuildRequires: mingw64-c-ares
BuildRequires: mingw64-libxml2
BuildRequires: mingw64-openssl
BuildRequires: mingw64-python3
BuildRequires: mingw64-zlib
%endif
%description
This package contains the HTTP/2 client, server and proxy programs.
%package -n libnghttp2
Summary: A library implementing the HTTP/2 protocol
%description -n libnghttp2
libnghttp2 is a library implementing the Hypertext Transfer Protocol
version 2 (HTTP/2) protocol in C.
%package -n libnghttp2-devel
Summary: Files needed for building applications with libnghttp2
Requires: libnghttp2%{?_isa} = %{version}-%{release}
Requires: pkgconfig
%description -n libnghttp2-devel
The libnghttp2-devel package includes libraries and header files needed
for building applications with libnghttp2.
%if %{with_mingw}
%package -n mingw32-libnghttp2
Summary: A library implementing the HTTP/2 protocol
%description -n mingw32-libnghttp2
libnghttp2 is a library implementing the Hypertext Transfer Protocol
version 2 (HTTP/2) protocol in C.
This is the MinGW cross-compiled Windows library.
%package -n mingw64-libnghttp2
Summary: A library implementing the HTTP/2 protocol
%description -n mingw64-libnghttp2
libnghttp2 is a library implementing the Hypertext Transfer Protocol
version 2 (HTTP/2) protocol in C.
This is the MinGW cross-compiled Windows library.
%{?mingw_debug_package}
%endif
%prep
%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'
%autosetup -p1
%build
mkdir build
pushd build
%define _configure ../configure
%configure PYTHON=%{__python3} \
--disable-hpack-tools \
--disable-python-bindings \
--disable-static \
--with-libxml2
# avoid using rpath
sed -i libtool \
-e 's/^runpath_var=.*/runpath_var=/' \
-e 's/^hardcode_libdir_flag_spec=".*"$/hardcode_libdir_flag_spec=""/'
%make_build
popd
%if %{with_mingw}
%mingw_configure --disable-hpack-tools --disable-static
%mingw_make_build
%endif
%install
pushd build
%make_install
install -D -m0444 -p contrib/nghttpx.service \
"$RPM_BUILD_ROOT%{_unitdir}/nghttpx.service"
popd
# not needed on Fedora/RHEL
rm -f "$RPM_BUILD_ROOT%{_libdir}/libnghttp2.la"
# will be installed via %%doc
rm -f "$RPM_BUILD_ROOT%{_datadir}/doc/nghttp2/README.rst"
%ldconfig_scriptlets -n libnghttp2
%if %{with_mingw}
%mingw_make_install
%mingw_debug_install_post
rm -f "${buildroot}%{mingw32_libdir}/libnghttp2.la"
rm -f "${buildroot}%{mingw64_libdir}/libnghttp2.la"
rm -f "%{buildroot}%{mingw32_datadir}/doc/nghttp2/README.rst"
rm -f "%{buildroot}%{mingw64_datadir}/doc/nghttp2/README.rst"
rm -r "%{buildroot}%{mingw32_mandir}/man1"
rm -r "%{buildroot}%{mingw64_mandir}/man1"
%endif
%post
%systemd_post nghttpx.service
%postun
%systemd_postun nghttpx.service
%check
# test the just built library instead of the system one, without using rpath
export "LD_LIBRARY_PATH=$RPM_BUILD_ROOT%{_libdir}:$LD_LIBRARY_PATH"
pushd build
%make_build check
popd
%files
%{_bindir}/h2load
%{_bindir}/nghttp
%{_bindir}/nghttpd
%{_bindir}/nghttpx
%{_datadir}/nghttp2
%{_mandir}/man1/h2load.1*
%{_mandir}/man1/nghttp.1*
%{_mandir}/man1/nghttpd.1*
%{_mandir}/man1/nghttpx.1*
%{_unitdir}/nghttpx.service
%files -n libnghttp2
%{_libdir}/libnghttp2.so.*
%{!?_licensedir:%global license %%doc}
%license COPYING
%files -n libnghttp2-devel
%{_includedir}/nghttp2
%{_libdir}/pkgconfig/libnghttp2.pc
%{_libdir}/libnghttp2.so
%doc README.rst
%if %{with_mingw}
%files -n mingw32-libnghttp2
%license COPYING
%doc README.rst
%{mingw32_bindir}/libnghttp2-14.dll
%{mingw32_libdir}/libnghttp2.dll.a
%{mingw32_libdir}/pkgconfig/libnghttp2.pc
%{mingw32_includedir}/nghttp2/
%{mingw32_datadir}/nghttp2/
%files -n mingw64-libnghttp2
%license COPYING
%doc README.rst
%{mingw64_bindir}/libnghttp2-14.dll
%{mingw64_libdir}/libnghttp2.dll.a
%{mingw64_libdir}/pkgconfig/libnghttp2.pc
%{mingw64_includedir}/nghttp2/
%{mingw64_datadir}/nghttp2/
%endif
%changelog
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 1.61.0-2
- Bump release for June 2024 mass rebuild
* Thu Apr 04 2024 Jan Macku <jamacku@redhat.com> 1.61.0-1
- update to the latest upstream release
- fixes CVE-2024-28182 - HTTP/2 CONTINUATION frames can be utilized for DoS attacks
* Wed Mar 06 2024 Yaakov Selkowitz <yselkowi@redhat.com> - 1.60.0-2
- Fix shebang of fetch-ocsp-response
* Mon Mar 04 2024 Jan Macku <jamacku@redhat.com> 1.60.0-1
- update to the latest upstream release
- update PGP key from https://keyserver.ubuntu.com/pks/lookup?op=vindex&search=0x7e8403d5d673c366
* Thu Jan 25 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.59.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Mon Jan 22 2024 Jan Macku <jamacku@redhat.com> 1.59.0-1
- update to the latest upstream release
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.58.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Mon Oct 30 2023 Jan Macku <jamacku@redhat.com> 1.58.0-1
- update to the latest upstream release
* Wed Oct 11 2023 Jan Macku <jamacku@redhat.com> 1.57.0-2
- fix mingw build
* Wed Oct 11 2023 Jan Macku <jamacku@redhat.com> 1.57.0-1
- update to the latest upstream release
- fixes CVE-2023-44487 - HTTP/2 Rapid Reset
* Fri Sep 15 2023 Marc-André Lureau <marcandre.lureau@redhat.com> - 1.56.0-2
- Add MinGW packages. rhbz#2102067
* Mon Sep 11 2023 Jan Macku <jamacku@redhat.com> 1.56.0-1
- update to the latest upstream release
* Mon Aug 07 2023 Lukáš Zaoral <lzaoral@redhat.com> - 1.55.1-3
- migrate to SPDX license format
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.55.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Mon Jul 17 2023 Jan Macku <jamacku@redhat.com> 1.55.1-1
- update to the latest upstream release
- fixes CVE-2023-35945 - memmory leak
* Thu Jul 13 2023 Jan Macku <jamacku@redhat.com> 1.55.0-1
- update to the latest upstream release
* Thu Jun 08 2023 Jan Macku <jamacku@redhat.com> 1.54.0-1
- update to the latest upstream release
* Thu May 11 2023 Kamil Dudka <kdudka@redhat.com> 1.53.0-1
- verify GPG signature of upstream tarball
- update to the latest upstream release
* Tue Feb 14 2023 Kamil Dudka <kdudka@redhat.com> 1.52.0-1
- update to the latest upstream release
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Tue Nov 15 2022 Kamil Dudka <kdudka@redhat.com> 1.51.0-1
- update to the latest upstream release
* Thu Sep 22 2022 Kamil Dudka <kdudka@redhat.com> 1.50.0-1
- update to the latest upstream release
* Tue Aug 23 2022 Kamil Dudka <kdudka@redhat.com> 1.49.0-1
- update to the latest upstream release
* Fri Jul 22 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.48.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Fri Jun 24 2022 Kamil Dudka <kdudka@redhat.com> 1.48.0-1
- update to the latest upstream release
* Fri Feb 25 2022 Kamil Dudka <kdudka@redhat.com> 1.47.0-1
- update to the latest upstream release
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.46.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Tue Oct 19 2021 Kamil Dudka <kdudka@redhat.com> 1.46.0-1
- update to the latest upstream release
* Tue Sep 21 2021 Kamil Dudka <kdudka@redhat.com> 1.45.1-1
- update to the latest upstream release
* Mon Sep 20 2021 Kamil Dudka <kdudka@redhat.com> 1.45.0-1
- update to the latest upstream release
* Tue Sep 14 2021 Sahana Prasad <sahana@redhat.com> - 1.44.0-3
- Rebuilt with OpenSSL 3.0.0
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.44.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Mon Jul 19 2021 Kamil Dudka <kdudka@redhat.com> 1.44.0-1
- update to the latest upstream release
* Tue Mar 30 2021 Jonathan Wakely <jwakely@redhat.com> - 1.43.0-2
- Rebuilt for removed libstdc++ symbol (#1937698)
* Tue Feb 02 2021 Kamil Dudka <kdudka@redhat.com> 1.43.0-1
- update to the latest upstream release
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.42.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Tue Nov 24 2020 Kamil Dudka <kdudka@redhat.com> 1.42.0-1
- update to the latest upstream release
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.41.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue Jul 14 2020 Tom Stellard <tstellar@redhat.com> - 1.41.0-2
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
* Tue Jun 02 2020 Kamil Dudka <kdudka@redhat.com> 1.41.0-1
- update to the latest upstream release
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.40.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Fri Nov 15 2019 Kamil Dudka <kdudka@redhat.com> 1.40.0-1
- update to the latest upstream release
* Thu Nov 14 2019 Kamil Dudka <kdudka@redhat.com> 1.39.2-2
- enable use of libxml2 to make `nghttp --get-assets` work (#1772462)
* Wed Aug 14 2019 Kamil Dudka <kdudka@redhat.com> 1.39.2-1
- update to the latest upstream release
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.39.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Tue Jun 11 2019 Kamil Dudka <kdudka@redhat.com> 1.39.1-1
- update to the latest upstream release
* Tue Jun 11 2019 Kamil Dudka <kdudka@redhat.com> 1.39.0-1
- update to the latest upstream release
* Thu Apr 18 2019 Kamil Dudka <kdudka@redhat.com> 1.38.0-1
- update to the latest upstream release
* Fri Mar 08 2019 Kamil Dudka <kdudka@redhat.com> 1.37.0-1
- update to the latest upstream release
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.36.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Fri Jan 18 2019 Kamil Dudka <kdudka@redhat.com> 1.36.0-1
- update to the latest upstream release
* Mon Dec 10 2018 Kamil Dudka <kdudka@redhat.com> 1.35.1-1
- update to the latest upstream release
* Fri Nov 23 2018 Kamil Dudka <kdudka@redhat.com> 1.35.0-1
- update to the latest upstream release
* Thu Oct 04 2018 Kamil Dudka <kdudka@redhat.com> 1.34.0-1
- update to the latest upstream release
* Mon Sep 03 2018 Kamil Dudka <kdudka@redhat.com> 1.33.0-1
- use python3 for build
- update to the latest upstream release
* Mon Aug 27 2018 Kamil Dudka <kdudka@redhat.com> 1.32.1-1
- update to the latest upstream bugfix release
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.32.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Wed May 09 2018 Kamil Dudka <kdudka@redhat.com> 1.32.0-1
- update to the latest upstream release
* Fri Apr 13 2018 Kamil Dudka <kdudka@redhat.com> 1.31.1-1
- update to the latest upstream release (fixes CVE-2018-1000168)
* Thu Mar 15 2018 Kamil Dudka <kdudka@redhat.com> 1.31.0-2
- make fetch-ocsp-response use Python 3
* Tue Feb 27 2018 Kamil Dudka <kdudka@redhat.com> 1.31.0-1
- update to the latest upstream release
* Mon Feb 19 2018 Kamil Dudka <kdudka@redhat.com> 1.30.0-3
- add explicit BR for the gcc-c++ compiler
* Thu Feb 08 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.30.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Mon Feb 05 2018 Kamil Dudka <kdudka@redhat.com> 1.30.0-1
- update to the latest upstream release
* Sat Feb 03 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.29.0-2
- Switch to %%ldconfig_scriptlets
* Tue Dec 19 2017 Kamil Dudka <kdudka@redhat.com> 1.29.0-1
- update to the latest upstream release
* Sun Nov 26 2017 Kamil Dudka <kdudka@redhat.com> 1.28.0-1
- update to the latest upstream release
* Wed Oct 25 2017 Kamil Dudka <kdudka@redhat.com> 1.27.0-1
- update to the latest upstream release
* Wed Sep 20 2017 Kamil Dudka <kdudka@redhat.com> 1.26.0-1
- update to the latest upstream release
* Fri Aug 18 2017 Kamil Dudka <kdudka@redhat.com> 1.25.0-1
- update to the latest upstream release
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.24.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
* Sat Jul 29 2017 Florian Weimer <fweimer@redhat.com> - 1.24.0-3
- Rebuild with binutils fix for ppc64le (#1475636)
* Wed Jul 26 2017 Kamil Dudka <kdudka@redhat.com> 1.24.0-2
- drop workaround for a GCC bug that has been fixed (#1358845)
* Sun Jul 02 2017 Kamil Dudka <kdudka@redhat.com> 1.24.0-1
- update to the latest upstream release
* Tue May 30 2017 Kamil Dudka <kdudka@redhat.com> 1.23.1-1
- update to the latest upstream release
* Sat May 27 2017 Kamil Dudka <kdudka@redhat.com> 1.23.0-1
- update to the latest upstream release
* Mon Apr 24 2017 Kamil Dudka <kdudka@redhat.com> 1.22.0-1
- update to the latest upstream release
* Mon Apr 10 2017 Kamil Dudka <kdudka@redhat.com> 1.21.1-1
- update to the latest upstream release
* Mon Mar 27 2017 Kamil Dudka <kdudka@redhat.com> 1.21.0-1
- update to the latest upstream release
* Sun Feb 26 2017 Tomasz Torcz <ttorcz@fedoraproject.org> - 1.20.0-1
- package systemd unit file (#1426929)
- update to latest upstream release
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 1.19.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Wed Jan 25 2017 Kamil Dudka <kdudka@redhat.com> 1.19.0-1
- update to the latest upstream release
* Thu Jan 05 2017 Kamil Dudka <kdudka@redhat.com> 1.18.1-1
- update to the latest upstream release
* Tue Dec 27 2016 Kamil Dudka <kdudka@redhat.com> 1.18.0-1
- update to the latest upstream release (requires c-ares for apps)
* Mon Nov 28 2016 Kamil Dudka <kdudka@redhat.com> 1.17.0-1
- update to the latest upstream release
* Tue Nov 15 2016 Kamil Dudka <kdudka@redhat.com> 1.16.1-1
- update to the latest upstream release
* Mon Oct 24 2016 Kamil Dudka <kdudka@redhat.com> 1.16.0-1
- update to the latest upstream release
* Mon Sep 26 2016 Kamil Dudka <kdudka@redhat.com> 1.15.0-1
- update to the latest upstream release
* Mon Sep 12 2016 Kamil Dudka <kdudka@redhat.com> 1.14.1-1
- update to the latest upstream release
* Thu Aug 25 2016 Kamil Dudka <kdudka@redhat.com> 1.14.0-1
- update to the latest upstream release
* Tue Jul 26 2016 Kamil Dudka <kdudka@redhat.com> 1.13.0-2
- prevent nghttpx from crashing on armv7hl (#1358845)
* Thu Jul 21 2016 Kamil Dudka <kdudka@redhat.com> 1.13.0-1
- update to the latest upstream release
* Mon Jun 27 2016 Kamil Dudka <kdudka@redhat.com> 1.12.0-1
- update to the latest upstream release
* Sun May 29 2016 Kamil Dudka <kdudka@redhat.com> 1.11.1-1
- update to the latest upstream release
* Thu May 26 2016 Kamil Dudka <kdudka@redhat.com> 1.11.0-1
- update to the latest upstream release
* Mon Apr 25 2016 Kamil Dudka <kdudka@redhat.com> 1.10.0-1
- update to the latest upstream release
* Sun Apr 03 2016 Kamil Dudka <kdudka@redhat.com> 1.9.2-1
- update to the latest upstream release
* Tue Mar 29 2016 Kamil Dudka <kdudka@redhat.com> 1.9.1-1
- update to the latest upstream release
* Thu Feb 25 2016 Kamil Dudka <kdudka@redhat.com> 1.8.0-1
- update to the latest upstream release
* Thu Feb 11 2016 Kamil Dudka <kdudka@redhat.com> 1.7.1-1
- update to the latest upstream release (fixes CVE-2016-1544)
* Fri Feb 05 2016 Kamil Dudka <kdudka@redhat.com> 1.7.0-3
- make the package compile with gcc-6
* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 1.7.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Mon Jan 25 2016 Kamil Dudka <kdudka@redhat.com> 1.7.0-1
- update to the latest upstream release
* Fri Dec 25 2015 Kamil Dudka <kdudka@redhat.com> 1.6.0-1
- update to the latest upstream release (fixes CVE-2015-8659)
* Thu Nov 26 2015 Kamil Dudka <kdudka@redhat.com> 1.5.0-1
- update to the latest upstream release
* Mon Oct 26 2015 Kamil Dudka <kdudka@redhat.com> 1.4.0-1
- update to the latest upstream release
* Thu Sep 24 2015 Kamil Dudka <kdudka@redhat.com> 1.3.4-1
- update to the latest upstream release
* Wed Sep 23 2015 Kamil Dudka <kdudka@redhat.com> 1.3.3-1
- update to the latest upstream release
* Wed Sep 16 2015 Kamil Dudka <kdudka@redhat.com> 1.3.2-1
- update to the latest upstream release
* Mon Sep 14 2015 Kamil Dudka <kdudka@redhat.com> 1.3.1-1
- update to the latest upstream release
* Mon Aug 31 2015 Kamil Dudka <kdudka@redhat.com> 1.3.0-1
- update to the latest upstream release
* Mon Aug 17 2015 Kamil Dudka <kdudka@redhat.com> 1.2.1-1
- update to the latest upstream release
* Sun Aug 09 2015 Kamil Dudka <kdudka@redhat.com> 1.2.0-1
- update to the latest upstream release
* Wed Jul 15 2015 Kamil Dudka <kdudka@redhat.com> 1.1.1-1
- update to the latest upstream release
* Tue Jun 30 2015 Kamil Dudka <kdudka@redhat.com> 1.0.5-1
- packaged for Fedora (#1237247)

2
sources Normal file
View File

@ -0,0 +1,2 @@
SHA512 (nghttp2-1.61.0.tar.xz) = 01e930d7caf464699505f92b76e2bc8192d168612dc564d2546812c42afea2fb81d552d70e8a5fed35e2bf5deadbec8eda095af94a2484bca41542988afce52a
SHA512 (nghttp2-1.61.0.tar.xz.asc) = cdc6cf1e01f9020a4e0823f7e1cec70c68e1942fbdf0ffbf8493dea185472f5777032a8bffcedff77b00e0df18f3d86718b308e9732bf0ee686f07add0d37d64

64
tatsuhiro-t.pgp Normal file
View File

@ -0,0 +1,64 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=bHHX
-----END PGP PUBLIC KEY BLOCK-----