Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pl_go_overrides()

go_download_sdk(
name = "go_sdk",
version = "1.24.0",
version = "1.24.4",
)

go_rules_dependencies()
Expand Down Expand Up @@ -238,7 +238,7 @@ go_download_sdk(

go_download_sdk(
name = "go_sdk_1_23",
version = "1.23.6",
version = "1.23.10",
)

# The go_sdk_boringcrypto SDK is used for testing boringcrypto specific functionality (TLS tracing).
Expand All @@ -251,7 +251,7 @@ go_download_sdk(
go_download_sdk(
name = "go_sdk_boringcrypto",
experiments = ["boringcrypto"],
version = "1.23.5",
version = "1.23.9",
)

pip_parse(
Expand Down
4 changes: 2 additions & 2 deletions bazel/pl_build_system.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
load("@rules_python//python:defs.bzl", "py_test")
load("//bazel:toolchain_transitions.bzl", "qemu_interactive_runner")

pl_boringcrypto_go_sdk = ["1.23.5"]
pl_supported_go_sdk_versions = ["1.18", "1.19", "1.20", "1.21", "1.22", "1.23"]
pl_boringcrypto_go_sdk = ["1.23.9"]
pl_supported_go_sdk_versions = ["1.18", "1.19", "1.20", "1.21", "1.22", "1.23", "1.24"]

# The last version in this list corresponds to the boringcrypto go sdk version.
pl_all_supported_go_sdk_versions = pl_supported_go_sdk_versions + pl_boringcrypto_go_sdk
Expand Down
8 changes: 4 additions & 4 deletions docker.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
DOCKER_IMAGE_TAG=202504142133
LINTER_IMAGE_DIGEST=0129dd524203f95a25f4343ec4499919db4434752375624a4cdbd51d463acdaf
DEV_IMAGE_DIGEST=f669bf0bc9db3ce03a48365a41e87de1a8e3e9be01bc5a1e10816412c671665e
DEV_IMAGE_WITH_EXTRAS_DIGEST=65535207f2fb805d45bb7997cf0a71abbd756cf8763db02c57838f8ee18f0c66
DOCKER_IMAGE_TAG=202506270326
LINTER_IMAGE_DIGEST=05aeeb210dec4b5753e55376aef7df013bb136a3ad70524fa1dff24f832b5c4e
DEV_IMAGE_DIGEST=f0a0c803733d6ad8c9104f745378ab9d7a95263a3f8882fc28f11c79c1200d1f
DEV_IMAGE_WITH_EXTRAS_DIGEST=17c8ce9c4bd4dba40cdd6e40bdee726237336dbd6581deca864ebe9302cff569
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module px.dev/pixie

go 1.24.0
go 1.24.4

require (
cloud.google.com/go v0.81.0
Expand Down
6 changes: 6 additions & 0 deletions src/stirling/source_connectors/socket_tracer/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,15 @@ pl_cc_bpf_test(
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_client:golang_1_21_grpc_client",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_client:golang_1_22_grpc_client",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_client:golang_1_23_grpc_client",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_client:golang_1_24_grpc_client",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_client:golang_boringcrypto_grpc_client",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_server:golang_1_18_grpc_server_with_certs",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_server:golang_1_19_grpc_server_with_certs",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_server:golang_1_20_grpc_server_with_certs",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_server:golang_1_21_grpc_server_with_certs",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_server:golang_1_22_grpc_server_with_certs",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_server:golang_1_23_grpc_server_with_certs",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_server:golang_1_24_grpc_server_with_certs",
"//src/stirling/source_connectors/socket_tracer/protocols/http2/testing/go_grpc_server:golang_boringcrypto_grpc_server_with_certs",
],
flaky = True,
Expand Down Expand Up @@ -364,6 +366,8 @@ pl_cc_bpf_test(
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_1_22_grpc_server_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_1_23_grpc_client_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_1_23_grpc_server_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_1_24_grpc_client_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_1_24_grpc_server_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_boringcrypto_grpc_client_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_boringcrypto_grpc_server_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:product_catalog_client_container",
Expand Down Expand Up @@ -586,6 +590,8 @@ pl_cc_bpf_test(
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_1_22_tls_server_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_1_23_tls_client_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_1_23_tls_server_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_1_24_tls_client_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_1_24_tls_server_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_boringcrypto_tls_client_container",
"//src/stirling/source_connectors/socket_tracer/testing/container_images:go_boringcrypto_tls_server_container",
"//src/stirling/testing:cc_library",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,19 @@ static __inline int32_t get_fd_from_http2_Framer(const void* framer_ptr,
static __inline int32_t get_fd_from_http_http2Framer(const void* framer_ptr,
const struct go_http2_symaddrs_t* symaddrs) {
REQUIRE_SYMADDR(symaddrs->http2Framer_w_offset, kInvalidFD);
REQUIRE_SYMADDR(symaddrs->http2bufferedWriter_w_offset, kInvalidFD);
int32_t inner_intf_offset = symaddrs->http2bufferedWriter_w_offset;
bool conn_intf = false;
// Go 1.24 dropped the io.Writer w member from http2bufferedWriter,
// in favor of a conn member (net.Conn interface).
// Go 1.23 struct:
// https://github.com/golang/go/blob/d375ae50633cdf1cd8536f2a199c382f9053b638/src/net/http/h2_bundle.go#L3552-L3556
// Go 1.24 struct:
// https://github.com/golang/go/blob/3901409b5d0fb7c85a3e6730a59943cc93b2835c/src/net/http/h2_bundle.go#L3733-L3739
if (inner_intf_offset == -1) {
inner_intf_offset = symaddrs->http2bufferedWriter_conn_offset;
conn_intf = true;
}
REQUIRE_SYMADDR(inner_intf_offset, kInvalidFD);

struct go_interface io_writer_interface;
BPF_PROBE_READ_VAR(io_writer_interface, framer_ptr + symaddrs->http2Framer_w_offset);
Expand All @@ -152,11 +164,13 @@ static __inline int32_t get_fd_from_http_http2Framer(const void* framer_ptr,
return kInvalidFD;
}

struct go_interface inner_io_writer_interface;
BPF_PROBE_READ_VAR(inner_io_writer_interface,
io_writer_interface.ptr + symaddrs->http2bufferedWriter_w_offset);
struct go_interface inner_intf;
BPF_PROBE_READ_VAR(inner_intf, io_writer_interface.ptr + inner_intf_offset);

return get_fd_from_io_writer_intf(inner_io_writer_interface.ptr);
if (conn_intf) {
return get_fd_from_conn_intf(inner_intf);
}
return get_fd_from_io_writer_intf(inner_intf.ptr);
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -525,7 +539,7 @@ int probe_http2_server_operate_headers(struct pt_regs* ctx) {
// Symbol:
// net/http.(*http2serverConn).processHeaders
//
// Verified to be stable from go1.?? to t go.1.13.
// Verified to be stable from go1.?? to go.1.24..
int probe_http_http2serverConn_processHeaders(struct pt_regs* ctx) {
uint32_t tgid = bpf_get_current_pid_tgid() >> 32;
struct go_http2_symaddrs_t* symaddrs = http2_symaddrs_map.lookup(&tgid);
Expand Down Expand Up @@ -629,7 +643,7 @@ int probe_http_http2serverConn_processHeaders(struct pt_regs* ctx) {
// Symbol:
// golang.org/x/net/http2/hpack.(*Encoder).WriteField
//
// Verified to be stable from at least go1.6 to t go.1.13.
// Verified to be stable from at least go1.6 to go.1.24.
int probe_hpack_header_encoder(struct pt_regs* ctx) {
uint32_t tgid = bpf_get_current_pid_tgid() >> 32;
struct go_http2_symaddrs_t* symaddrs = http2_symaddrs_map.lookup(&tgid);
Expand Down Expand Up @@ -679,7 +693,7 @@ int probe_hpack_header_encoder(struct pt_regs* ctx) {
// Symbol:
// net/http.(*http2writeResHeaders).writeFrame
//
// Verified to be stable from go1.?? to t go.1.13.
// Verified to be stable from go1.?? to go.1.24.
int probe_http_http2writeResHeaders_write_frame(struct pt_regs* ctx) {
uint32_t tgid = bpf_get_current_pid_tgid() >> 32;
struct go_http2_symaddrs_t* symaddrs = http2_symaddrs_map.lookup(&tgid);
Expand Down Expand Up @@ -857,7 +871,7 @@ static __inline void go_http2_submit_data(struct pt_regs* ctx, enum http2_probe_
// Symbol:
// golang.org/x/net/http2.(*Framer).checkFrameOrder
//
// Verified to be stable from at least go1.6 to t go.1.13.
// Verified to be stable from at least go1.6 to go.1.24.
int probe_http2_framer_check_frame_order(struct pt_regs* ctx) {
uint32_t tgid = bpf_get_current_pid_tgid() >> 32;
struct go_http2_symaddrs_t* symaddrs = http2_symaddrs_map.lookup(&tgid);
Expand Down Expand Up @@ -962,7 +976,7 @@ int probe_http2_framer_check_frame_order(struct pt_regs* ctx) {
// Symbol:
// net/http.(*http2Framer).checkFrameOrder
//
// Verified to be stable from at least go1.?? to go.1.13.
// Verified to be stable from at least go1.?? to go.1.24.
int probe_http_http2framer_check_frame_order(struct pt_regs* ctx) {
uint32_t tgid = bpf_get_current_pid_tgid() >> 32;
struct go_http2_symaddrs_t* symaddrs = http2_symaddrs_map.lookup(&tgid);
Expand Down Expand Up @@ -1066,7 +1080,7 @@ int probe_http_http2framer_check_frame_order(struct pt_regs* ctx) {
// Symbol:
// golang.org/x/net/http2.(*Framer).WriteDataPadded
//
// Verified to be stable from go1.7 to t go.1.13.
// Verified to be stable from go1.7 to go.1.24.
int probe_http2_framer_write_data(struct pt_regs* ctx) {
uint32_t tgid = bpf_get_current_pid_tgid() >> 32;
struct go_http2_symaddrs_t* symaddrs = http2_symaddrs_map.lookup(&tgid);
Expand Down Expand Up @@ -1134,7 +1148,7 @@ int probe_http2_framer_write_data(struct pt_regs* ctx) {
// Symbol:
// net/http.(*http2Framer).WriteDataPadded
//
// Verified to be stable from go1.?? to t go.1.13.
// Verified to be stable from go1.?? to go.1.24.
int probe_http_http2framer_write_data(struct pt_regs* ctx) {
uint32_t tgid = bpf_get_current_pid_tgid() >> 32;
struct go_http2_symaddrs_t* symaddrs = http2_symaddrs_map.lookup(&tgid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,25 @@ static __inline int32_t get_fd_from_conn_intf_core(struct go_interface conn_intf
REQUIRE_SYMADDR(symaddrs->FD_Sysfd_offset, kInvalidFD);

if (conn_intf.type == symaddrs->internal_syscallConn) {
// TODO(ddelnano): The 4.14 verifier has stricter bounds checking limits when reading memory
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider just dropping 4.14 support since it is EOL already.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created #2224 to track this.

// offsets. Without this check, the verifier rejects the program. This can be removed when 4.14
// kernel support is dropped.
if (symaddrs->syscallConn_conn_offset < 0 || symaddrs->syscallConn_conn_offset > 1024) {
return kInvalidFD;
}
Comment on lines +180 to +182
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I arbitrarily picked 1024 for this bounds check. From the opentelemetry-go-instrumentation offset file, I don't see this offset found for any version of the google.golang.org/grpc/credentials/internal package (source)

REQUIRE_SYMADDR(symaddrs->syscallConn_conn_offset, kInvalidFD);
const int kSyscallConnConnOffset = 0;
bpf_probe_read(&conn_intf, sizeof(conn_intf),
conn_intf.ptr + symaddrs->syscallConn_conn_offset);
}

if (conn_intf.type == symaddrs->tls_Conn) {
// TODO(ddelnano): The 4.14 verifier has stricter bounds checking limits when reading memory
// offsets. Without this check, the verifier rejects the program. This can be removed when 4.14
// kernel support is dropped.
if (symaddrs->tlsConn_conn_offset < 0 || symaddrs->tlsConn_conn_offset > 1024) {
return kInvalidFD;
}
Comment on lines +193 to +195
Copy link
Copy Markdown
Member Author

@ddelnano ddelnano Jun 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I arbitrarily picked 1024 for this bounds check. From the opentelemetry-go-instrumentation offset file, this offset has been 0 from Go 1.19 to 1.24 (source).

REQUIRE_SYMADDR(symaddrs->tlsConn_conn_offset, kInvalidFD);
bpf_probe_read(&conn_intf, sizeof(conn_intf), conn_intf.ptr + symaddrs->tlsConn_conn_offset);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ struct go_http2_symaddrs_t {

// Members of net/http.http2bufferedWriter
int32_t http2bufferedWriter_w_offset; // 0
// Go 1.24 switched from a w io.Writer member to a conn net.Conn one.
int32_t http2bufferedWriter_conn_offset;
};

struct go_tls_symaddrs_t {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_1_22_tls_server_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_1_23_tls_client_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_1_23_tls_server_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_1_24_tls_client_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_1_24_tls_server_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_boringcrypto_tls_client_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_boringcrypto_tls_server_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/protocol_checkers.h"
Expand Down Expand Up @@ -101,6 +103,11 @@ struct Go1_23TLSClientServerContainers {
using GoTLSClientContainer = ::px::stirling::testing::Go1_23_TLSClientContainer;
};

struct Go1_24TLSClientServerContainers {
using GoTLSServerContainer = ::px::stirling::testing::Go1_24_TLSServerContainer;
using GoTLSClientContainer = ::px::stirling::testing::Go1_24_TLSClientContainer;
};

struct GoBoringCryptoTLSClientServerContainers {
using GoTLSServerContainer = ::px::stirling::testing::GoBoringCryptoTLSServerContainer;
using GoTLSClientContainer = ::px::stirling::testing::GoBoringCryptoTLSClientContainer;
Expand All @@ -109,7 +116,7 @@ struct GoBoringCryptoTLSClientServerContainers {
typedef ::testing::Types<GoBoringCryptoTLSClientServerContainers, Go1_18TLSClientServerContainers,
Go1_19TLSClientServerContainers, Go1_20TLSClientServerContainers,
Go1_21TLSClientServerContainers, Go1_22TLSClientServerContainers,
Go1_23TLSClientServerContainers>
Go1_23TLSClientServerContainers, Go1_24TLSClientServerContainers>
GoVersions;
TYPED_TEST_SUITE(GoTLSTraceTest, GoVersions);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ INSTANTIATE_TEST_SUITE_P(SecurityModeTest, GRPCTraceTest,
TestParams{"1_21", true, true}, TestParams{"1_21", true, false},
TestParams{"1_22", true, true}, TestParams{"1_22", true, false},
TestParams{"1_23", true, true}, TestParams{"1_23", true, false},
TestParams{"1_24", true, true}, TestParams{"1_24", true, false},
TestParams{"boringcrypto", true, true}));

class PyGRPCTraceTest : public testing::SocketTraceBPFTestFixture</* TClientSideTracing */ false> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_1_22_grpc_server_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_1_23_grpc_client_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_1_23_grpc_server_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_1_24_grpc_client_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_1_24_grpc_server_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_boringcrypto_grpc_client_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/go_boringcrypto_grpc_server_container.h"
#include "src/stirling/source_connectors/socket_tracer/testing/container_images/product_catalog_client_container.h"
Expand Down Expand Up @@ -105,6 +107,11 @@ struct Go1_23GRPCClientServerContainers {
using ClientContainer = ::px::stirling::testing::Go1_23_GRPCClientContainer;
};

struct Go1_24GRPCClientServerContainers {
using ServerContainer = ::px::stirling::testing::Go1_24_GRPCServerContainer;
using ClientContainer = ::px::stirling::testing::Go1_24_GRPCClientContainer;
};

struct GoBoringCryptoGRPCClientServerContainers {
using ServerContainer = ::px::stirling::testing::GoBoringCryptoGRPCServerContainer;
using ClientContainer = ::px::stirling::testing::GoBoringCryptoGRPCClientContainer;
Expand All @@ -113,7 +120,7 @@ struct GoBoringCryptoGRPCClientServerContainers {
typedef ::testing::Types<GoBoringCryptoGRPCClientServerContainers, Go1_18GRPCClientServerContainers,
Go1_19GRPCClientServerContainers, Go1_20GRPCClientServerContainers,
Go1_21GRPCClientServerContainers, Go1_22GRPCClientServerContainers,
Go1_23GRPCClientServerContainers>
Go1_23GRPCClientServerContainers, Go1_24GRPCClientServerContainers>
GoVersions;
TYPED_TEST_SUITE(HTTP2TraceTest, GoVersions);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2018- The Pixie Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <string>

#include "src/common/testing/test_environment.h"
#include "src/common/testing/test_utils/container_runner.h"

namespace px {
namespace stirling {
namespace testing {

class Go1_24_GRPCClientContainer : public ContainerRunner {
public:
Go1_24_GRPCClientContainer()
: ContainerRunner(::px::testing::BazelRunfilePath(kBazelImageTar), kContainerNamePrefix,
kReadyMessage) {}

private:
static constexpr std::string_view kBazelImageTar =
"src/stirling/testing/demo_apps/go_grpc_tls_pl/client/golang_1_24_grpc_tls_client.tar";
static constexpr std::string_view kContainerNamePrefix = "grpc_client";
static constexpr std::string_view kReadyMessage = "";
};

} // namespace testing
} // namespace stirling
} // namespace px
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2018- The Pixie Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/

#pragma once

#include <string>

#include "src/common/testing/test_environment.h"
#include "src/common/testing/test_utils/container_runner.h"

namespace px {
namespace stirling {
namespace testing {

class Go1_24_GRPCServerContainer : public ContainerRunner {
public:
Go1_24_GRPCServerContainer()
: ContainerRunner(::px::testing::BazelRunfilePath(kBazelImageTar), kContainerNamePrefix,
kReadyMessage) {}

static constexpr std::string_view kBazelImageTar =
"src/stirling/testing/demo_apps/go_grpc_tls_pl/server/golang_1_24_grpc_tls_server.tar";

private:
static constexpr std::string_view kContainerNamePrefix = "grpc_server";
static constexpr std::string_view kReadyMessage = "Starting HTTP/2 server";
};

} // namespace testing
} // namespace stirling
} // namespace px
Loading
Loading