Add support for abstract unix domain sockets (#27906)

* Add failing end2end test for inconsistent percent-decoding of URIs

* Add passing h2_local_abstract_uds end2end tests

* null-safe string_view

* mac doesn't UDS

* mac doesn't do *abstract* UDS
pull/27943/head
AJ Heller 3 years ago committed by GitHub
parent 13d98176b5
commit c79cdc0ae8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/core/ext/filters/client_channel/client_channel.cc
  2. 3
      src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
  3. 12
      src/core/ext/transport/chttp2/server/chttp2_server.cc
  4. 2
      src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
  5. 4
      src/core/lib/iomgr/event_engine/endpoint.cc
  6. 4
      src/core/lib/iomgr/event_engine/tcp.cc
  7. 13
      src/core/lib/iomgr/tcp_client_posix.cc
  8. 4
      src/core/lib/iomgr/tcp_client_posix.h
  9. 2
      src/core/lib/iomgr/tcp_client_windows.cc
  10. 4
      src/core/lib/iomgr/tcp_posix.cc
  11. 2
      src/core/lib/iomgr/tcp_posix.h
  12. 4
      src/core/lib/iomgr/tcp_server_posix.cc
  13. 2
      src/core/lib/iomgr/tcp_server_windows.cc
  14. 4
      src/core/lib/iomgr/tcp_windows.cc
  15. 2
      src/core/lib/iomgr/tcp_windows.h
  16. 2
      src/core/lib/iomgr/unix_sockets_posix.cc
  17. 2
      src/core/lib/iomgr/unix_sockets_posix.h
  18. 2
      src/core/lib/iomgr/unix_sockets_posix_noop.cc
  19. 5
      src/core/lib/security/security_connector/local/local_security_connector.cc
  20. 38
      src/core/lib/uri/uri_parser.cc
  21. 2
      src/core/lib/uri/uri_parser.h
  22. 70
      test/core/end2end/fixtures/h2_local_abstract_uds_percent_encoded.cc
  23. 75
      test/core/end2end/fixtures/h2_local_uds_percent_encoded.cc
  24. 10
      test/core/end2end/generate_tests.bzl

@ -1091,7 +1091,7 @@ ClientChannel::ClientChannel(grpc_channel_element_args* args,
// resolver creation will succeed later.
if (!ResolverRegistry::IsValidTarget(uri_to_resolve_)) {
*error = GRPC_ERROR_CREATE_FROM_CPP_STRING(
absl::StrCat("the target uri is not valid: ", uri_to_resolve_.c_str()));
absl::StrCat("the target uri is not valid: ", uri_to_resolve_));
return;
}
// Strip out service config channel arg, so that it doesn't affect

@ -91,7 +91,8 @@ bool ParseUri(const URI& uri,
// Construct addresses.
bool errors_found = false;
for (absl::string_view ith_path : absl::StrSplit(uri.path(), ',')) {
URI ith_uri(uri.scheme(), "", std::string(ith_path), {}, "");
URI ith_uri(uri.scheme(), "",
std::string(ith_path.data(), ith_path.length()), {}, "");
grpc_resolved_address addr;
if (!parse(ith_uri, &addr)) {
errors_found = true;

@ -29,6 +29,7 @@
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/strip.h"
#include <grpc/grpc.h>
#include <grpc/impl/codegen/grpc_types.h>
@ -53,6 +54,7 @@
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/server.h"
#include "src/core/lib/uri/uri_parser.h"
namespace grpc_core {
namespace {
@ -856,17 +858,19 @@ grpc_error_handle Chttp2ServerAddPort(Server* server, const char* addr,
*port_num = -1;
grpc_resolved_addresses* resolved = nullptr;
std::vector<grpc_error_handle> error_list;
std::string parsed_addr = URI::PercentDecode(absl::NullSafeStringView(addr));
// Using lambda to avoid use of goto.
grpc_error_handle error = [&]() {
grpc_error_handle error = GRPC_ERROR_NONE;
if (absl::StartsWith(addr, kUnixUriPrefix)) {
if (absl::StartsWith(parsed_addr, kUnixUriPrefix)) {
error = grpc_resolve_unix_domain_address(
addr + sizeof(kUnixUriPrefix) - 1, &resolved);
absl::StripPrefix(parsed_addr, kUnixUriPrefix), &resolved);
} else if (absl::StartsWith(addr, kUnixAbstractUriPrefix)) {
error = grpc_resolve_unix_abstract_domain_address(
addr + sizeof(kUnixAbstractUriPrefix) - 1, &resolved);
absl::StripPrefix(parsed_addr, kUnixAbstractUriPrefix), &resolved);
} else {
error = grpc_blocking_resolve_address(addr, "https", &resolved);
error = grpc_blocking_resolve_address(parsed_addr.c_str(), "https",
&resolved);
}
if (error != GRPC_ERROR_NONE) return error;
// Create a listener for each resolved address.

@ -48,7 +48,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
grpc_resource_quota* resource_quota =
grpc_resource_quota_create(name.c_str());
grpc_endpoint* server_endpoint = grpc_tcp_create(
grpc_fd_create(fd, name.c_str(), true), server_args, name.c_str(),
grpc_fd_create(fd, name.c_str(), true), server_args, name,
grpc_slice_allocator_create(resource_quota, name, server_args));
grpc_transport* transport = grpc_create_chttp2_transport(
server_args, server_endpoint, false /* is_client */,

@ -162,8 +162,8 @@ grpc_event_engine_endpoint* grpc_tcp_server_endpoint_create(
return endpoint;
}
grpc_endpoint* grpc_tcp_create(const grpc_channel_args* channel_args,
absl::string_view peer_address) {
grpc_endpoint* grpc_tcp_create(/*channel_args=*/const grpc_channel_args*,
/*peer_address=*/absl::string_view) {
auto endpoint = new grpc_event_engine_endpoint;
endpoint->base.vtable = &grpc_event_engine_endpoint_vtable;
return &endpoint->base;

@ -284,8 +284,8 @@ grpc_fd* grpc_fd_create(int /* fd */, const char* /* name */,
}
grpc_endpoint* grpc_tcp_client_create_from_fd(
grpc_fd* /* fd */, const grpc_channel_args* /* channel_args */,
const char* /* addr_str */, grpc_slice_allocator* slice_allocator) {
/*fd=*/grpc_fd*, /*channel_args=*/const grpc_channel_args*,
/*addr_str=*/absl::string_view, grpc_slice_allocator* slice_allocator) {
grpc_slice_allocator_destroy(slice_allocator);
return nullptr;
}

@ -127,8 +127,8 @@ static void tc_on_alarm(void* acp, grpc_error_handle error) {
}
grpc_endpoint* grpc_tcp_client_create_from_fd(
grpc_fd* fd, const grpc_channel_args* channel_args, const char* addr_str,
grpc_slice_allocator* slice_allocator) {
grpc_fd* fd, const grpc_channel_args* channel_args,
absl::string_view addr_str, grpc_slice_allocator* slice_allocator) {
return grpc_tcp_create(fd, channel_args, addr_str, slice_allocator);
}
@ -177,8 +177,8 @@ static void on_writable(void* acp, grpc_error_handle error) {
switch (so_error) {
case 0:
grpc_pollset_set_del_fd(ac->interested_parties, fd);
*ep = grpc_tcp_client_create_from_fd(
fd, ac->channel_args, ac->addr_str.c_str(), ac->slice_allocator);
*ep = grpc_tcp_client_create_from_fd(fd, ac->channel_args, ac->addr_str,
ac->slice_allocator);
ac->slice_allocator = nullptr;
fd = nullptr;
break;
@ -292,9 +292,8 @@ void grpc_tcp_client_create_from_prepared_fd(
grpc_fd* fdobj = grpc_fd_create(fd, name.c_str(), true);
if (err >= 0) {
*ep = grpc_tcp_client_create_from_fd(fdobj, channel_args,
grpc_sockaddr_to_uri(addr).c_str(),
slice_allocator);
*ep = grpc_tcp_client_create_from_fd(
fdobj, channel_args, grpc_sockaddr_to_uri(addr), slice_allocator);
grpc_core::ExecCtx::Run(DEBUG_LOCATION, closure, GRPC_ERROR_NONE);
return;
}

@ -34,8 +34,8 @@
Returns: a new endpoint
*/
grpc_endpoint* grpc_tcp_client_create_from_fd(
grpc_fd* fd, const grpc_channel_args* channel_args, const char* addr_str,
grpc_slice_allocator* slice_allocator);
grpc_fd* fd, const grpc_channel_args* channel_args,
absl::string_view addr_str, grpc_slice_allocator* slice_allocator);
/* Return a configured, unbound, unconnected TCP client fd.

@ -109,7 +109,7 @@ static void on_connect(void* acp, grpc_error_handle error) {
error = GRPC_WSA_ERROR(WSAGetLastError(), "ConnectEx");
closesocket(socket->socket);
} else {
*ep = grpc_tcp_create(socket, ac->channel_args, ac->addr_name.c_str(),
*ep = grpc_tcp_create(socket, ac->channel_args, ac->addr_name,
ac->slice_allocator);
ac->slice_allocator = nullptr;
socket = nullptr;

@ -1669,7 +1669,7 @@ static const grpc_endpoint_vtable vtable = {tcp_read,
grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd,
const grpc_channel_args* channel_args,
const char* peer_string,
absl::string_view peer_string,
grpc_slice_allocator* slice_allocator) {
static constexpr bool kZerocpTxEnabledDefault = false;
int tcp_read_chunk_size = GRPC_TCP_DEFAULT_READ_SLICE_SIZE;
@ -1727,7 +1727,7 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd,
grpc_tcp* tcp = new grpc_tcp(tcp_tx_zerocopy_max_simult_sends,
tcp_tx_zerocopy_send_bytes_thresh);
tcp->base.vtable = &vtable;
tcp->peer_string = peer_string;
tcp->peer_string = std::string(peer_string.data(), peer_string.size());
tcp->fd = grpc_fd_wrapped_fd(em_fd);
tcp->slice_allocator = slice_allocator;
grpc_resolved_address resolved_local_addr;

@ -43,7 +43,7 @@ extern grpc_core::TraceFlag grpc_tcp_trace;
/// Create a tcp endpoint given a file desciptor and a read slice size.
/// Takes ownership of \a fd. Takes ownership of the \a slice_allocator.
grpc_endpoint* grpc_tcp_create(grpc_fd* fd, const grpc_channel_args* args,
const char* peer_string,
absl::string_view peer_string,
grpc_slice_allocator* slice_allocator);
/// Return the tcp endpoint's fd, or -1 if this is not available. Does not

@ -268,7 +268,7 @@ static void on_read(void* arg, grpc_error_handle err) {
acceptor->external_connection = false;
sp->server->on_accept_cb(
sp->server->on_accept_cb_arg,
grpc_tcp_create(fdobj, sp->server->channel_args, addr_str.c_str(),
grpc_tcp_create(fdobj, sp->server->channel_args, addr_str,
grpc_slice_allocator_factory_create_slice_allocator(
sp->server->slice_allocator_factory,
absl::StrCat("tcp_server_posix:", addr_str),
@ -618,7 +618,7 @@ class ExternalConnectionHandler : public grpc_core::TcpServerFdHandler {
s_->on_accept_cb(
s_->on_accept_cb_arg,
grpc_tcp_create(
fdobj, s_->channel_args, addr_str.c_str(),
fdobj, s_->channel_args, addr_str,
grpc_slice_allocator_factory_create_slice_allocator(
s_->slice_allocator_factory, addr_str, s_->channel_args)),
read_notifier_pollset, acceptor);

@ -360,7 +360,7 @@ static void on_accept(void* arg, grpc_error_handle error) {
std::string fd_name = absl::StrCat("tcp_server:", peer_name_string);
ep = grpc_tcp_create(
grpc_winsocket_create(sock, fd_name.c_str()),
sp->server->channel_args, peer_name_string.c_str(),
sp->server->channel_args, peer_name_string,
grpc_slice_allocator_factory_create_slice_allocator(
sp->server->slice_allocator_factory, peer_name_string));
} else {

@ -502,7 +502,7 @@ static grpc_endpoint_vtable vtable = {win_read,
grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket,
grpc_channel_args* channel_args,
const char* peer_string,
absl::string_view peer_string,
grpc_slice_allocator* slice_allocator) {
grpc_tcp* tcp = new grpc_tcp;
memset(tcp, 0, sizeof(grpc_tcp));
@ -521,7 +521,7 @@ grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket,
} else {
tcp->local_address = grpc_sockaddr_to_uri(&resolved_local_addr);
}
tcp->peer_string = peer_string;
tcp->peer_string = std::string(peer_string.data(), peer_string.size());
grpc_slice_buffer_init(&tcp->last_read_buffer);
tcp->slice_allocator = slice_allocator;
return &tcp->base;

@ -42,7 +42,7 @@
*/
grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket,
grpc_channel_args* channel_args,
const char* peer_string,
absl::string_view peer_string,
grpc_slice_allocator* slice_allocator);
grpc_error_handle grpc_tcp_prepare_socket(SOCKET sock);

@ -41,7 +41,7 @@ void grpc_create_socketpair_if_unix(int sv[2]) {
}
grpc_error_handle grpc_resolve_unix_domain_address(
const char* name, grpc_resolved_addresses** addresses) {
absl::string_view name, grpc_resolved_addresses** addresses) {
*addresses = static_cast<grpc_resolved_addresses*>(
gpr_malloc(sizeof(grpc_resolved_addresses)));
(*addresses)->naddrs = 1;

@ -33,7 +33,7 @@
void grpc_create_socketpair_if_unix(int sv[2]);
grpc_error_handle grpc_resolve_unix_domain_address(
const char* name, grpc_resolved_addresses** addresses);
absl::string_view name, grpc_resolved_addresses** addresses);
grpc_error_handle grpc_resolve_unix_abstract_domain_address(
absl::string_view name, grpc_resolved_addresses** addresses);

@ -34,7 +34,7 @@ void grpc_create_socketpair_if_unix(int /* sv */[2]) {
}
grpc_error_handle grpc_resolve_unix_domain_address(
const char* /* name */, grpc_resolved_addresses** addresses) {
/*name=*/absl::string_view, grpc_resolved_addresses** addresses) {
*addresses = NULL;
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Unix domain sockets are not supported on Windows");

@ -44,6 +44,7 @@
#include "src/core/tsi/local_transport_security.h"
#define GRPC_UDS_URI_PATTERN "unix:"
#define GRPC_ABSTRACT_UDS_URI_PATTERN "unix-abstract:"
#define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE "local"
namespace {
@ -270,7 +271,9 @@ grpc_local_channel_security_connector_create(
const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg);
if (creds->connect_type() == UDS &&
strncmp(GRPC_UDS_URI_PATTERN, server_uri_str,
strlen(GRPC_UDS_URI_PATTERN)) != 0) {
strlen(GRPC_UDS_URI_PATTERN)) != 0 &&
strncmp(GRPC_ABSTRACT_UDS_URI_PATTERN, server_uri_str,
strlen(GRPC_ABSTRACT_UDS_URI_PATTERN)) != 0) {
gpr_log(GPR_ERROR,
"Invalid UDS target name to "
"grpc_local_channel_security_connector_create()");

@ -34,11 +34,29 @@
#include "src/core/lib/gpr/string.h"
namespace grpc_core {
namespace {
// Checks if this string is made up of pchars, '/', '?', and '%' exclusively.
// See https://tools.ietf.org/html/rfc3986#section-3.4
bool IsPCharString(absl::string_view str) {
return (str.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"?/:@\\-._~!$&'()*+,;=%") ==
absl::string_view::npos);
}
absl::Status MakeInvalidURIStatus(absl::string_view part_name,
absl::string_view uri,
absl::string_view extra) {
return absl::InvalidArgumentError(absl::StrFormat(
"Could not parse '%s' from uri '%s'. %s", part_name, uri, extra));
}
} // namespace
// Similar to `grpc_permissive_percent_decode_slice`, this %-decodes all valid
// triplets, and passes through the rest verbatim.
std::string PercentDecode(absl::string_view str) {
std::string URI::PercentDecode(absl::string_view str) {
if (str.empty() || !absl::StrContains(str, "%")) {
return std::string(str);
}
@ -64,24 +82,6 @@ std::string PercentDecode(absl::string_view str) {
return out;
}
// Checks if this string is made up of pchars, '/', '?', and '%' exclusively.
// See https://tools.ietf.org/html/rfc3986#section-3.4
bool IsPCharString(absl::string_view str) {
return (str.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"?/:@\\-._~!$&'()*+,;=%") ==
absl::string_view::npos);
}
absl::Status MakeInvalidURIStatus(absl::string_view part_name,
absl::string_view uri,
absl::string_view extra) {
return absl::InvalidArgumentError(absl::StrFormat(
"Could not parse '%s' from uri '%s'. %s", part_name, uri, extra));
}
} // namespace
absl::StatusOr<URI> URI::Parse(absl::string_view uri_text) {
absl::StatusOr<std::string> decoded;
absl::string_view remaining = uri_text;

@ -56,6 +56,8 @@ class URI {
URI(URI&&) = default;
URI& operator=(URI&&) = default;
static std::string PercentDecode(absl::string_view str);
const std::string& scheme() const { return scheme_; }
const std::string& authority() const { return authority_; }
const std::string& path() const { return path_; }

@ -0,0 +1,70 @@
// Copyright 2021 gRPC 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.
#include <unistd.h>
#include "absl/strings/str_format.h"
#include <grpc/support/string_util.h>
#include "test/core/end2end/end2end_tests.h"
#include "test/core/end2end/fixtures/local_util.h"
#include "test/core/util/test_config.h"
static int unique{0};
static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_uds(
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) {
grpc_end2end_test_fixture f =
grpc_end2end_local_chttp2_create_fixture_fullstack();
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
static_cast<grpc_end2end_local_fullstack_fixture_data*>(f.fixture_data)
->localaddr = absl::StrFormat(
"unix-abstract:grpc_fullstack_test.%%00.%d.%" PRId64 ".%" PRId32 ".%d",
getpid(), now.tv_sec, now.tv_nsec, ++unique);
return f;
}
static void chttp2_init_client_fullstack_uds(grpc_end2end_test_fixture* f,
grpc_channel_args* client_args) {
grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, UDS);
}
static void chttp2_init_server_fullstack_uds(grpc_end2end_test_fixture* f,
grpc_channel_args* client_args) {
grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, UDS);
}
/* All test configurations */
static grpc_end2end_test_config configs[] = {
{"chttp2/fullstack_local_abstract_uds_percent_encoded",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
nullptr, chttp2_create_fixture_fullstack_uds,
chttp2_init_client_fullstack_uds, chttp2_init_server_fullstack_uds,
grpc_end2end_local_chttp2_tear_down_fullstack}};
int main(int argc, char** argv) {
size_t i;
grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
grpc_end2end_tests(argc, argv, configs[i]);
}
grpc_shutdown();
return 0;
}

@ -0,0 +1,75 @@
/*
*
* Copyright 2015 gRPC 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.
*
*/
#include <inttypes.h>
#include <unistd.h>
#include "absl/strings/str_format.h"
#include <grpc/support/string_util.h>
#include "test/core/end2end/end2end_tests.h"
#include "test/core/end2end/fixtures/local_util.h"
#include "test/core/util/test_config.h"
static int unique = 1;
static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_uds(
grpc_channel_args* /*client_args*/, grpc_channel_args* /*server_args*/) {
grpc_end2end_test_fixture f =
grpc_end2end_local_chttp2_create_fixture_fullstack();
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
static_cast<grpc_end2end_local_fullstack_fixture_data*>(f.fixture_data)
->localaddr = absl::StrFormat(
"unix:/tmp/grpc_fullstack_test.%%25.%d.%" PRId64 ".%" PRId32 ".%d",
getpid(), now.tv_sec, now.tv_nsec, unique++);
return f;
}
static void chttp2_init_client_fullstack_uds(grpc_end2end_test_fixture* f,
grpc_channel_args* client_args) {
grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, UDS);
}
static void chttp2_init_server_fullstack_uds(grpc_end2end_test_fixture* f,
grpc_channel_args* client_args) {
grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, UDS);
}
/* All test configurations */
static grpc_end2end_test_config configs[] = {
{"chttp2/fullstack_local_uds_percent_encoded",
FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
nullptr, chttp2_create_fixture_fullstack_uds,
chttp2_init_client_fullstack_uds, chttp2_init_server_fullstack_uds,
grpc_end2end_local_chttp2_tear_down_fullstack}};
int main(int argc, char** argv) {
size_t i;
grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
grpc_end2end_tests(argc, argv, configs[i]);
}
grpc_shutdown();
return 0;
}

@ -91,11 +91,21 @@ END2END_FIXTURES = {
"h2_ssl": _fixture_options(secure = True),
"h2_ssl_cred_reload": _fixture_options(secure = True),
"h2_tls": _fixture_options(secure = True),
"h2_local_abstract_uds_percent_encoded": _fixture_options(
secure = True,
dns_resolver = False,
_platforms = ["linux", "posix"],
),
"h2_local_uds": _fixture_options(
secure = True,
dns_resolver = False,
_platforms = ["linux", "mac", "posix"],
),
"h2_local_uds_percent_encoded": _fixture_options(
secure = True,
dns_resolver = False,
_platforms = ["linux", "mac", "posix"],
),
"h2_local_ipv4": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]),
"h2_local_ipv6": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]),
"h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = True),

Loading…
Cancel
Save